diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index 65aa5a333..e7055e810 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -51,7 +51,7 @@ void remove_bad(ExPolygons &expolygons); // helpr for heal shape // Return true when erase otherwise false -bool remove_same_neighbor(Points &points); +bool remove_same_neighbor(Polygon &points); bool remove_same_neighbor(Polygons &polygons); bool remove_same_neighbor(ExPolygons &expolygons); @@ -272,14 +272,22 @@ void priv::remove_bad(ExPolygons &expolygons) { remove_bad(expolygon.holes); } -bool priv::remove_same_neighbor(Slic3r::Points &points) +bool priv::remove_same_neighbor(Slic3r::Polygon &polygon) { + Points &points = polygon.points; if (points.empty()) return false; auto last = std::unique(points.begin(), points.end()); - if (last == points.end()) return false; + + // remove first and last neighbor duplication + if (const Point& last_point = *(last - 1); + last_point == points.front()) { + --last; + } + + // no duplicits + if (last == points.end()) return false; + points.erase(last, points.end()); - // clear points without area - if (points.size() <= 2) points.clear(); return true; } @@ -287,34 +295,30 @@ bool priv::remove_same_neighbor(Polygons &polygons) { if (polygons.empty()) return false; bool exist = false; for (Polygon& polygon : polygons) - exist |= remove_same_neighbor(polygon.points); + exist |= remove_same_neighbor(polygon); // remove empty polygons polygons.erase( std::remove_if(polygons.begin(), polygons.end(), - [](const Polygon &p) { return p.empty(); }), + [](const Polygon &p) { return p.points.size() <= 2; }), polygons.end()); return exist; } bool priv::remove_same_neighbor(ExPolygons &expolygons) { if(expolygons.empty()) return false; - bool exist = false; + bool remove_from_holes = false; + bool remove_from_contour = false; for (ExPolygon &expoly : expolygons) { - exist |= remove_same_neighbor(expoly.contour.points); - Polygons &holes = expoly.holes; - for (Polygon &hole : holes) - exist |= remove_same_neighbor(hole.points); - holes.erase( - std::remove_if(holes.begin(), holes.end(), - [](const Polygon &p) { return p.size() < 3; }), - holes.end()); + remove_from_contour |= remove_same_neighbor(expoly.contour); + remove_from_holes |= remove_same_neighbor(expoly.holes); } - - // Removing of point could create polygon with less than 3 points - if (exist) - remove_bad(expolygons); - - return exist; + // Removing of expolygons without contour + if (remove_from_contour) + expolygons.erase( + std::remove_if(expolygons.begin(), expolygons.end(), + [](const ExPolygon &p) { return p.contour.points.size() <=2; }), + expolygons.end()); + return remove_from_holes || remove_from_contour; } Points priv::collect_close_points(const ExPolygons &expolygons, double distance) { @@ -502,9 +506,9 @@ bool priv::remove_self_intersections(ExPolygons &shape, unsigned max_iteration) hole.translate(p); holes.push_back(hole); } - // union overlapped holes - if (holes.size() > 1) - holes = Slic3r::union_(holes); + // Union of overlapped holes is not neccessary + // Clipper calculate winding number separately for each input parameter + // if (holes.size() > 1) holes = Slic3r::union_(holes); shape = Slic3r::diff_ex(shape, holes, ApplySafetyOffset::Yes); // TODO: find where diff ex could create same neighbor @@ -630,7 +634,6 @@ bool priv::heal_dupl_inter(ExPolygons &shape, unsigned max_iteration) holes.push_back(hole); } - holes = Slic3r::union_(holes); shape = Slic3r::diff_ex(shape, holes, ApplySafetyOffset::Yes); // prepare for next loop diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index bd4101dc9..79d6d191c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -119,10 +119,14 @@ namespace Slic3r { // we assume that heating is always slower than cooling, so no need to block gcode += gcodegen.writer().set_temperature (this->_get_temp(gcodegen) + gcodegen.config().standby_temperature_delta.value, false, extruder_id); + gcode.pop_back(); + gcode += " ;cooldown\n"; // this is a marker for GCodeProcessor, so it can supress the commands when needed } } else { // Use the value from filament settings. That one is absolute, not delta. gcode += gcodegen.writer().set_temperature(filament_idle_temp.get_at(extruder_id), false, extruder_id); + gcode.pop_back(); + gcode += " ;cooldown\n"; // this is a marker for GCodeProcessor, so it can supress the commands when needed } return gcode; diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9b371e405..a56c1e132 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -441,6 +441,9 @@ void GCodeProcessorResult::reset() { max_print_height = 0.0f; settings_ids.reset(); extruders_count = 0; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + backtrace_enabled = false; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE extruder_colors = std::vector(); filament_diameters = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER); filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); @@ -458,6 +461,9 @@ void GCodeProcessorResult::reset() { max_print_height = 0.0f; settings_ids.reset(); extruders_count = 0; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + backtrace_enabled = false; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE extruder_colors = std::vector(); filament_diameters = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER); filament_densities = std::vector(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY); @@ -551,6 +557,10 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_producer = EProducer::PrusaSlicer; m_flavor = config.gcode_flavor; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + m_result.backtrace_enabled = is_XL_printer(config); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE + size_t extruders_count = config.nozzle_diameter.values.size(); m_result.extruders_count = extruders_count; @@ -560,10 +570,15 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_result.filament_densities.resize(extruders_count); m_result.filament_cost.resize(extruders_count); m_extruder_temps.resize(extruders_count); + m_extruder_temps_config.resize(extruders_count); + m_extruder_temps_first_layer_config.resize(extruders_count); + m_is_XL_printer = is_XL_printer(config); for (size_t i = 0; i < extruders_count; ++ i) { m_extruder_offsets[i] = to_3d(config.extruder_offset.get_at(i).cast().eval(), 0.f); m_extruder_colors[i] = static_cast(i); + m_extruder_temps_config[i] = static_cast(config.temperature.get_at(i)); + m_extruder_temps_first_layer_config[i] = static_cast(config.first_layer_temperature.get_at(i)); m_result.filament_diameters[i] = static_cast(config.filament_diameter.get_at(i)); m_result.filament_densities[i] = static_cast(config.filament_density.get_at(i)); m_result.filament_cost[i] = static_cast(config.filament_cost.get_at(i)); @@ -3461,18 +3476,261 @@ void GCodeProcessor::post_process() last_exported_stop[i] = time_in_minutes(m_time_processor.machines[i].time); } +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + // Helper class to modify and export gcode to file + class ExportLines + { + public: + struct Backtrace + { + float time{ 60.0f }; + unsigned int steps{ 10 }; + float time_step() const { return time / float(steps); } + }; + + enum class EWriteType + { + BySize, + ByTime + }; + + private: + struct LineData + { + std::string line; + float time; + }; + +#ifndef NDEBUG + class Statistics + { + ExportLines& m_parent; + size_t m_max_size{ 0 }; + size_t m_lines_count{ 0 }; + size_t m_max_lines_count{ 0 }; + + public: + explicit Statistics(ExportLines& parent) + : m_parent(parent) + {} + + void add_line(size_t line_size) { + ++m_lines_count; + m_max_size = std::max(m_max_size, m_parent.get_size() + line_size); + m_max_lines_count = std::max(m_max_lines_count, m_lines_count); + } + + void remove_line() { --m_lines_count; } + void remove_all_lines() { m_lines_count = 0; } + }; + + Statistics m_statistics; +#endif // NDEBUG + + EWriteType m_write_type{ EWriteType::BySize }; + // Time machine containing g1 times cache + TimeMachine& m_machine; + // Current time + float m_time{ 0.0f }; + // Current size in bytes + size_t m_size{ 0 }; + + // gcode lines cache + std::deque m_lines; + size_t m_added_lines_counter{ 0 }; + // map of gcode line ids from original to final + // used to update m_result.moves[].gcode_id + std::vector> m_gcode_lines_map; + + size_t m_curr_g1_id{ 0 }; + size_t m_out_file_pos{ 0 }; + + public: + ExportLines(EWriteType type, TimeMachine& machine) +#ifndef NDEBUG + : m_statistics(*this), m_write_type(type), m_machine(machine) {} +#else + : m_write_type(type), m_machine(machine) {} +#endif // NDEBUG + + void update(size_t lines_counter, size_t g1_lines_counter) { + m_gcode_lines_map.push_back({ lines_counter, 0 }); + + if (g1_lines_counter == 0) + return; + + auto init_it = m_machine.g1_times_cache.begin() + m_curr_g1_id; + auto it = init_it; + while (it != m_machine.g1_times_cache.end() && it->id < g1_lines_counter + 1) { + ++it; + ++m_curr_g1_id; + } + + if (it != init_it || m_curr_g1_id == 0) + m_time = it->elapsed_time; + } + + // add the given gcode line to the cache + void append_line(const std::string& line) { + m_lines.push_back({ line, m_time }); +#ifndef NDEBUG + m_statistics.add_line(line.length()); +#endif // NDEBUG + m_size += line.length(); + ++m_added_lines_counter; + assert(!m_gcode_lines_map.empty()); + m_gcode_lines_map.back().second = m_added_lines_counter; + } + + // Insert the gcode lines required by the command cmd by backtracing into the cache + void insert_lines(const Backtrace& backtrace, const std::string& cmd, std::function line_inserter, + std::function line_replacer) { + assert(!m_lines.empty()); + const float time_step = backtrace.time_step(); + size_t rev_it_dist = 0; // distance from the end of the cache of the starting point of the backtrace + float last_time_insertion = 0.0f; // used to avoid inserting two lines at the same time + for (unsigned int i = 0; i < backtrace.steps; ++i) { + const float backtrace_time_i = (i + 1) * time_step; + const float time_threshold_i = m_time - backtrace_time_i; + auto rev_it = m_lines.rbegin() + rev_it_dist; + auto start_rev_it = rev_it; + + // backtrace into the cache to find the place where to insert the line + while (rev_it != m_lines.rend() && rev_it->time > time_threshold_i && GCodeReader::GCodeLine::extract_cmd(rev_it->line) != cmd) { + rev_it->line = line_replacer(rev_it->line); + ++rev_it; + } + + // we met the previous evenience of cmd. stop inserting lines + if (rev_it != m_lines.rend() && GCodeReader::GCodeLine::extract_cmd(rev_it->line) == cmd) + break; + + // insert the line for the current step + if (rev_it != m_lines.rend() && rev_it != start_rev_it && rev_it->time != last_time_insertion) { + last_time_insertion = rev_it->time; + const std::string out_line = line_inserter(i + 1, last_time_insertion, m_time - last_time_insertion); + rev_it_dist = std::distance(m_lines.rbegin(), rev_it) + 1; + const auto new_it = m_lines.insert(rev_it.base(), { out_line, rev_it->time }); +#ifndef NDEBUG + m_statistics.add_line(out_line.length()); +#endif // NDEBUG + m_size += out_line.length(); + // synchronize gcode lines map + for (auto map_it = m_gcode_lines_map.rbegin(); map_it != m_gcode_lines_map.rbegin() + rev_it_dist - 1; ++map_it) { + ++map_it->second; + } + + ++m_added_lines_counter; + } + } + } + + // write to file: + // m_write_type == EWriteType::ByTime - all lines older than m_time - backtrace_time + // m_write_type == EWriteType::BySize - all lines if current size is greater than 65535 bytes + void write(FilePtr& out, float backtrace_time, GCodeProcessorResult& result, const std::string& out_path) { + if (m_lines.empty()) + return; + + // collect lines to write into a single string + std::string out_string; + if (!m_lines.empty()) { + if (m_write_type == EWriteType::ByTime) { + while (m_lines.front().time < m_time - backtrace_time) { + const LineData& data = m_lines.front(); + out_string += data.line; + m_size -= data.line.length(); + m_lines.pop_front(); +#ifndef NDEBUG + m_statistics.remove_line(); +#endif // NDEBUG + } + } + else { + if (m_size > 65535) { + while (!m_lines.empty()) { + out_string += m_lines.front().line; + m_lines.pop_front(); + } + m_size = 0; +#ifndef NDEBUG + m_statistics.remove_all_lines(); +#endif // NDEBUG + } + } + } + + write_to_file(out, out_string, result, out_path); + } + + // flush the current content of the cache to file + void flush(FilePtr& out, GCodeProcessorResult& result, const std::string& out_path) { + // collect lines to flush into a single string + std::string out_string; + while (!m_lines.empty()) { + out_string += m_lines.front().line; + m_lines.pop_front(); + } + m_size = 0; +#ifndef NDEBUG + m_statistics.remove_all_lines(); +#endif // NDEBUG + + write_to_file(out, out_string, result, out_path); + } + + void synchronize_moves(GCodeProcessorResult& result) const { + auto it = m_gcode_lines_map.begin(); + for (GCodeProcessorResult::MoveVertex& move : result.moves) { + while (it != m_gcode_lines_map.end() && it->first < move.gcode_id) { + ++it; + } + if (it != m_gcode_lines_map.end() && it->first == move.gcode_id) + move.gcode_id = it->second; + } + } + + size_t get_size() const { return m_size; } + + private: + void write_to_file(FilePtr& out, const std::string& out_string, GCodeProcessorResult& result, const std::string& out_path) { + if (!out_string.empty()) { + fwrite((const void*)out_string.c_str(), 1, out_string.length(), out.f); + if (ferror(out.f)) { + out.close(); + boost::nowide::remove(out_path.c_str()); + throw Slic3r::RuntimeError(std::string("GCode processor post process export failed.\nIs the disk full?\n")); + } + for (size_t i = 0; i < out_string.size(); ++i) { + if (out_string[i] == '\n') + result.lines_ends.emplace_back(m_out_file_pos + i + 1); + } + m_out_file_pos += out_string.size(); + } + } + }; + + ExportLines export_lines(m_result.backtrace_enabled ? ExportLines::EWriteType::ByTime : ExportLines::EWriteType::BySize, m_time_processor.machines[0]); +#else // buffer line to export only when greater than 64K to reduce writing calls std::string export_line; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE // replace placeholder lines with the proper final value // gcode_line is in/out parameter, to reduce expensive memory allocation auto process_placeholders = [&](std::string& gcode_line) { +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + bool processed = false; +#else unsigned int extra_lines_count = 0; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE // remove trailing '\n' auto line = std::string_view(gcode_line).substr(0, gcode_line.length() - 1); +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE std::string ret; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE if (line.length() > 1) { line = line.substr(1); if (m_time_processor.export_remaining_time_enabled && @@ -3481,17 +3739,29 @@ void GCodeProcessor::post_process() const TimeMachine& machine = m_time_processor.machines[i]; if (machine.enabled) { // export pair +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(format_line_M73_main(machine.line_m73_main_mask.c_str(), + (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100, + (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0)); + processed = true; +#else ret += format_line_M73_main(machine.line_m73_main_mask.c_str(), (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100, (line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0); ++extra_lines_count; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE // export remaining time to next printer stop if (line == reserved_tag(ETags::First_Line_M73_Placeholder) && !machine.stop_times.empty()) { - int to_export_stop = time_in_minutes(machine.stop_times.front().elapsed_time); + const int to_export_stop = time_in_minutes(machine.stop_times.front().elapsed_time); +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop)); + last_exported_stop[i] = to_export_stop; +#else ret += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop); last_exported_stop[i] = to_export_stop; ++extra_lines_count; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE } } } @@ -3505,7 +3775,12 @@ void GCodeProcessor::post_process() sprintf(buf, "; estimated printing time (%s mode) = %s\n", (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent", get_time_dhms(machine.time).c_str()); +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(buf); + processed = true; +#else ret += buf; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE } } for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { @@ -3516,16 +3791,25 @@ void GCodeProcessor::post_process() sprintf(buf, "; estimated first layer printing time (%s mode) = %s\n", (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent", get_time_dhms(machine.layers_time.empty() ? 0.f : machine.layers_time.front()).c_str()); +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(buf); + processed = true; +#else ret += buf; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE } } } } +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + return processed; +#else if (!ret.empty()) // Not moving the move operator on purpose, so that the gcode_line allocation will grow and it will not be reallocated after handful of lines are processed. gcode_line = ret; return std::tuple(!ret.empty(), (extra_lines_count == 0) ? extra_lines_count : extra_lines_count - 1); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE }; std::vector filament_mm(m_result.extruders_count, 0.0); @@ -3599,10 +3883,16 @@ void GCodeProcessor::post_process() time_in_minutes, format_time_float, format_line_M73_main, format_line_M73_stop_int, format_line_M73_stop_float, time_in_last_minute, // Caches, to be modified &g1_times_cache_it, &last_exported_main, &last_exported_stop, +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + &export_lines] +#else // String output &export_line] +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE (const size_t g1_lines_counter) { +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE unsigned int exported_lines_count = 0; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE if (m_time_processor.export_remaining_time_enabled) { for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { const TimeMachine& machine = m_time_processor.machines[i]; @@ -3616,10 +3906,17 @@ void GCodeProcessor::post_process() std::pair to_export_main = { int(100.0f * it->elapsed_time / machine.time), time_in_minutes(machine.time - it->elapsed_time) }; if (last_exported_main[i] != to_export_main) { +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(format_line_M73_main(machine.line_m73_main_mask.c_str(), + to_export_main.first, to_export_main.second)); +#else export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(), to_export_main.first, to_export_main.second); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE last_exported_main[i] = to_export_main; +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE ++exported_lines_count; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE } // export remaining time to next printer stop auto it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), it->elapsed_time, @@ -3629,9 +3926,15 @@ void GCodeProcessor::post_process() if (last_exported_stop[i] != to_export_stop) { if (to_export_stop > 0) { if (last_exported_stop[i] != to_export_stop) { +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.append_line(format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop)); +#else export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE last_exported_stop[i] = to_export_stop; +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE ++exported_lines_count; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE } } else { @@ -3650,13 +3953,22 @@ void GCodeProcessor::post_process() } if (is_last) { +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + if (std::distance(machine.stop_times.begin(), it_stop) == static_cast(machine.stop_times.size() - 1)) + export_lines.append_line(format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop)); + else + export_lines.append_line(format_line_M73_stop_float(machine.line_m73_stop_mask.c_str(), time_in_last_minute(it_stop->elapsed_time - it->elapsed_time))); +#else if (std::distance(machine.stop_times.begin(), it_stop) == static_cast(machine.stop_times.size() - 1)) export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop); else export_line += format_line_M73_stop_float(machine.line_m73_stop_mask.c_str(), time_in_last_minute(it_stop->elapsed_time - it->elapsed_time)); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE last_exported_stop[i] = to_export_stop; +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE ++exported_lines_count; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE } } } @@ -3665,12 +3977,50 @@ void GCodeProcessor::post_process() } } } +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE return exported_lines_count; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE }; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + // add lines XXX to exported gcode + auto process_line_T = [this, &export_lines](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { + const std::string cmd = GCodeReader::GCodeLine::extract_cmd(gcode_line); + if (cmd.size() >= 2) { + std::stringstream ss(cmd.substr(1)); + int tool_number = -1; + ss >> tool_number; + if (tool_number != -1) + export_lines.insert_lines(backtrace, cmd, + // line inserter + [tool_number, this](unsigned int id, float time, float time_diff) { + int temperature = int( m_layer_id != 1 ? m_extruder_temps_config[tool_number] : m_extruder_temps_first_layer_config[tool_number]); + const std::string out = "M104 T" + std::to_string(tool_number) + " P" + std::to_string(int(std::round(time_diff))) + " S" + std::to_string(temperature) + "\n"; + return out; + }, + // line replacer + [this, tool_number](const std::string& line) { + if (GCodeReader::GCodeLine::cmd_is(line, "M104")) { + GCodeReader::GCodeLine gline; + GCodeReader reader; + reader.parse_line(line, [&gline](GCodeReader& reader, const GCodeReader::GCodeLine& l) { gline = l; }); + + float val; + if (gline.has_value('T', val) && gline.raw().find("cooldown") != std::string::npos && m_is_XL_printer) { + if (static_cast(val) == tool_number) + return std::string("; removed M104\n"); + } + } + return line; + }); + } + }; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE + + m_result.lines_ends.clear(); +#if !ENABLE_GCODE_POSTPROCESS_BACKTRACE // helper function to write to disk size_t out_file_pos = 0; - m_result.lines_ends.clear(); auto write_string = [this, &export_line, &out, &out_path, &out_file_pos](const std::string& str) { fwrite((const void*)export_line.c_str(), 1, export_line.length(), out.f); if (ferror(out.f)) { @@ -3684,9 +4034,18 @@ void GCodeProcessor::post_process() out_file_pos += export_line.size(); export_line.clear(); }; +#endif // !ENABLE_GCODE_POSTPROCESS_BACKTRACE unsigned int line_id = 0; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + // Backtrace data for Tx gcode lines + static const ExportLines::Backtrace backtrace_T = { 120.0f, 10 }; + // In case there are multiple sources of backtracing, keeps track of the longest backtrack time needed + // to flush the backtrace cache accordingly + float max_backtrace_time = 120.0f; +#else std::vector> offsets; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE { // Read the input stream 64kB at a time, extract lines and process them. @@ -3710,14 +4069,39 @@ void GCodeProcessor::post_process() gcode_line.insert(gcode_line.end(), it, it_end); if (eol) { ++line_id; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.update(line_id, g1_lines_counter); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE gcode_line += "\n"; // replace placeholder lines +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + bool processed = process_placeholders(gcode_line); + if (processed) + gcode_line.clear(); +#else auto [processed, lines_added_count] = process_placeholders(gcode_line); if (processed && lines_added_count > 0) offsets.push_back({ line_id, lines_added_count }); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE if (!processed) processed = process_used_filament(gcode_line); +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + if (!processed && !is_temporary_decoration(gcode_line)) { + if (GCodeReader::GCodeLine::cmd_is(gcode_line, "G1")) + // add lines M73 where needed + process_line_G1(g1_lines_counter++); + else if (m_result.backtrace_enabled && GCodeReader::GCodeLine::cmd_starts_with(gcode_line, "T")) { + // add lines XXX where needed + process_line_T(gcode_line, g1_lines_counter, backtrace_T); + max_backtrace_time = std::max(max_backtrace_time, backtrace_T.time); + } + } + + if (!gcode_line.empty()) + export_lines.append_line(gcode_line); + export_lines.write(out, 1.1f * max_backtrace_time, m_result, out_path); +#else if (!processed && !is_temporary_decoration(gcode_line) && GCodeReader::GCodeLine::cmd_is(gcode_line, "G1")) { // remove temporary lines, add lines M73 where needed unsigned int extra_lines_count = process_line_G1(g1_lines_counter++); @@ -3728,6 +4112,7 @@ void GCodeProcessor::post_process() export_line += gcode_line; if (export_line.length() > 65535) write_string(export_line); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE gcode_line.clear(); } // Skip EOL. @@ -3742,12 +4127,19 @@ void GCodeProcessor::post_process() } } +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.flush(out, m_result, out_path); +#else if (!export_line.empty()) write_string(export_line); +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE out.close(); in.close(); +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + export_lines.synchronize_moves(m_result); +#else // updates moves' gcode ids which have been modified by the insertion of the M73 lines unsigned int curr_offset_id = 0; unsigned int total_offset = 0; @@ -3758,6 +4150,7 @@ void GCodeProcessor::post_process() } move.gcode_id += total_offset; } +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE if (rename_file(out_path, m_result.filename)) throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + m_result.filename + '\n' + @@ -3908,6 +4301,8 @@ void GCodeProcessor::set_travel_acceleration(PrintEstimatedStatistics::ETimeMode float GCodeProcessor::get_filament_load_time(size_t extruder_id) { + if (m_is_XL_printer) + return 4.5f; // FIXME return (m_time_processor.filament_load_times.empty() || m_time_processor.extruder_unloaded) ? 0.0f : ((extruder_id < m_time_processor.filament_load_times.size()) ? @@ -3916,6 +4311,8 @@ float GCodeProcessor::get_filament_load_time(size_t extruder_id) float GCodeProcessor::get_filament_unload_time(size_t extruder_id) { + if (m_is_XL_printer) + return 0.f; // FIXME return (m_time_processor.filament_unload_times.empty() || m_time_processor.extruder_unloaded) ? 0.0f : ((extruder_id < m_time_processor.filament_unload_times.size()) ? diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 05656c7fd..856d5b31f 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -125,6 +125,9 @@ namespace Slic3r { float max_print_height; SettingsIds settings_ids; size_t extruders_count; +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + bool backtrace_enabled; +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE std::vector extruder_colors; std::vector filament_diameters; std::vector filament_densities; @@ -543,6 +546,9 @@ namespace Slic3r { unsigned char m_extruder_id; ExtruderColors m_extruder_colors; ExtruderTemps m_extruder_temps; + ExtruderTemps m_extruder_temps_config; + ExtruderTemps m_extruder_temps_first_layer_config; + bool m_is_XL_printer = false; float m_parking_position; float m_extra_loading_move; float m_extruded_last_z; diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 7fdbb6915..54c6199ec 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1346,6 +1346,36 @@ std::pair WipeTower::get_wipe_tower_cone_base(double width, doub return std::make_pair(R, support_scale); } +// Static method to extract wipe_volumes[from][to] from the configuration. +std::vector> WipeTower::extract_wipe_volumes(const PrintConfig& config) +{ + // Get wiping matrix to get number of extruders and convert vector to vector: + std::vector wiping_matrix(cast(config.wiping_volumes_matrix.values)); + + // The values shall only be used when SEMM is enabled. The purging for other printers + // is determined by filament_minimal_purge_on_wipe_tower. + if (! config.single_extruder_multi_material.value) + std::fill(wiping_matrix.begin(), wiping_matrix.end(), 0.f); + + // Extract purging volumes for each extruder pair: + std::vector> wipe_volumes; + const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON); + for (unsigned int i = 0; i(wiping_matrix.begin()+i*number_of_extruders, wiping_matrix.begin()+(i+1)*number_of_extruders)); + + // Also include filament_minimal_purge_on_wipe_tower. This is needed for the preview. + for (unsigned int i = 0; i get_wipe_tower_cone_base(double width, double height, double depth, double angle_deg); + static std::vector> extract_wipe_volumes(const PrintConfig& config); struct Extrusion { diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index 25ba6ee0b..bf85a5131 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -71,6 +71,19 @@ public: return strncmp(cmd, cmd_test, len) == 0 && GCodeReader::is_end_of_word(cmd[len]); } +#if ENABLE_GCODE_POSTPROCESS_BACKTRACE + static bool cmd_starts_with(const std::string& gcode_line, const char* cmd_test) { + return strncmp(GCodeReader::skip_whitespaces(gcode_line.c_str()), cmd_test, strlen(cmd_test)) == 0; + } + + static std::string extract_cmd(const std::string& gcode_line) { + GCodeLine temp; + temp.m_raw = gcode_line; + const std::string_view cmd = temp.cmd(); + return { cmd.begin(), cmd.end() }; + } +#endif // ENABLE_GCODE_POSTPROCESS_BACKTRACE + private: std::string m_raw; float m_axis[NUM_AXES]; diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 2cc34be0e..5542d73ee 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -395,7 +395,6 @@ Vec3d extract_rotation(const Transform3d& transform) return extract_rotation(m); } -#if ENABLE_WORLD_COORDINATE Transform3d Transformation::get_offset_matrix() const { return translation_transform(get_offset()); @@ -461,57 +460,12 @@ Transform3d Transformation::get_rotation_matrix() const { return extract_rotation_matrix(m_matrix); } -#else -bool Transformation::Flags::needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const -{ - return (this->dont_translate != dont_translate) || (this->dont_rotate != dont_rotate) || (this->dont_scale != dont_scale) || (this->dont_mirror != dont_mirror); -} - -void Transformation::Flags::set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) -{ - this->dont_translate = dont_translate; - this->dont_rotate = dont_rotate; - this->dont_scale = dont_scale; - this->dont_mirror = dont_mirror; -} - -Transformation::Transformation() -{ - reset(); -} - -Transformation::Transformation(const Transform3d& transform) -{ - set_from_transform(transform); -} - -void Transformation::set_offset(const Vec3d& offset) -{ - set_offset(X, offset.x()); - set_offset(Y, offset.y()); - set_offset(Z, offset.z()); -} - -void Transformation::set_offset(Axis axis, double offset) -{ - if (m_offset(axis) != offset) { - m_offset(axis) = offset; - m_dirty = true; - } -} -#endif // ENABLE_WORLD_COORDINATE void Transformation::set_rotation(const Vec3d& rotation) { -#if ENABLE_WORLD_COORDINATE const Vec3d offset = get_offset(); m_matrix = rotation_transform(rotation) * extract_scale(m_matrix); m_matrix.translation() = offset; -#else - set_rotation(X, rotation.x()); - set_rotation(Y, rotation.y()); - set_rotation(Z, rotation.z()); -#endif // ENABLE_WORLD_COORDINATE } void Transformation::set_rotation(Axis axis, double rotation) @@ -520,7 +474,6 @@ void Transformation::set_rotation(Axis axis, double rotation) if (is_approx(std::abs(rotation), 2.0 * double(PI))) rotation = 0.0; -#if ENABLE_WORLD_COORDINATE auto [curr_rotation, scale] = extract_rotation_scale(m_matrix); Vec3d angles = extract_rotation(curr_rotation); angles[axis] = rotation; @@ -528,15 +481,8 @@ void Transformation::set_rotation(Axis axis, double rotation) const Vec3d offset = get_offset(); m_matrix = rotation_transform(angles) * scale; m_matrix.translation() = offset; -#else - if (m_rotation(axis) != rotation) { - m_rotation(axis) = rotation; - m_dirty = true; - } -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE Vec3d Transformation::get_scaling_factor() const { const Transform3d scale = extract_scale(m_matrix); @@ -551,26 +497,18 @@ Transform3d Transformation::get_scaling_factor_matrix() const scale(2, 2) = std::abs(scale(2, 2)); return scale; } -#endif // ENABLE_WORLD_COORDINATE void Transformation::set_scaling_factor(const Vec3d& scaling_factor) { -#if ENABLE_WORLD_COORDINATE assert(scaling_factor.x() > 0.0 && scaling_factor.y() > 0.0 && scaling_factor.z() > 0.0); const Vec3d offset = get_offset(); m_matrix = extract_rotation_matrix(m_matrix) * scale_transform(scaling_factor); m_matrix.translation() = offset; -#else - set_scaling_factor(X, scaling_factor.x()); - set_scaling_factor(Y, scaling_factor.y()); - set_scaling_factor(Z, scaling_factor.z()); -#endif // ENABLE_WORLD_COORDINATE } void Transformation::set_scaling_factor(Axis axis, double scaling_factor) { -#if ENABLE_WORLD_COORDINATE assert(scaling_factor > 0.0); auto [rotation, scale] = extract_rotation_scale(m_matrix); @@ -579,15 +517,8 @@ void Transformation::set_scaling_factor(Axis axis, double scaling_factor) const Vec3d offset = get_offset(); m_matrix = rotation * scale; m_matrix.translation() = offset; -#else - if (m_scaling_factor(axis) != std::abs(scaling_factor)) { - m_scaling_factor(axis) = std::abs(scaling_factor); - m_dirty = true; - } -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE Vec3d Transformation::get_mirror() const { const Transform3d scale = extract_scale(m_matrix); @@ -602,11 +533,9 @@ Transform3d Transformation::get_mirror_matrix() const scale(2, 2) = scale(2, 2) / std::abs(scale(2, 2)); return scale; } -#endif // ENABLE_WORLD_COORDINATE void Transformation::set_mirror(const Vec3d& mirror) { -#if ENABLE_WORLD_COORDINATE Vec3d copy(mirror); const Vec3d abs_mirror = copy.cwiseAbs(); for (int i = 0; i < 3; ++i) { @@ -627,11 +556,6 @@ void Transformation::set_mirror(const Vec3d& mirror) const Vec3d offset = get_offset(); m_matrix = rotation * scale; m_matrix.translation() = offset; -#else - set_mirror(X, mirror.x()); - set_mirror(Y, mirror.y()); - set_mirror(Z, mirror.z()); -#endif // ENABLE_WORLD_COORDINATE } void Transformation::set_mirror(Axis axis, double mirror) @@ -642,7 +566,6 @@ void Transformation::set_mirror(Axis axis, double mirror) else if (abs_mirror != 1.0) mirror /= abs_mirror; -#if ENABLE_WORLD_COORDINATE auto [rotation, scale] = extract_rotation_scale(m_matrix); const double curr_scale = scale(axis, axis); const double sign = curr_scale * mirror; @@ -652,74 +575,18 @@ void Transformation::set_mirror(Axis axis, double mirror) const Vec3d offset = get_offset(); m_matrix = rotation * scale; m_matrix.translation() = offset; -#else - if (m_mirror(axis) != mirror) { - m_mirror(axis) = mirror; - m_dirty = true; - } -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE bool Transformation::has_skew() const { return contains_skew(m_matrix); } -#else -void Transformation::set_from_transform(const Transform3d& transform) -{ - // offset - set_offset(transform.matrix().block(0, 3, 3, 1)); - - Eigen::Matrix m3x3 = transform.matrix().block(0, 0, 3, 3); - - // mirror - // it is impossible to reconstruct the original mirroring factors from a matrix, - // we can only detect if the matrix contains a left handed reference system - // in which case we reorient it back to right handed by mirroring the x axis - Vec3d mirror = Vec3d::Ones(); - if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0) { - mirror.x() = -1.0; - // remove mirror - m3x3.col(0) *= -1.0; - } - set_mirror(mirror); - - // scale - set_scaling_factor(Vec3d(m3x3.col(0).norm(), m3x3.col(1).norm(), m3x3.col(2).norm())); - - // remove scale - m3x3.col(0).normalize(); - m3x3.col(1).normalize(); - m3x3.col(2).normalize(); - - // rotation - set_rotation(extract_rotation(m3x3)); - - // forces matrix recalculation matrix - m_matrix = get_matrix(); - -// // debug check -// if (!m_matrix.isApprox(transform)) -// std::cout << "something went wrong in extracting data from matrix" << std::endl; -} -#endif // ENABLE_WORLD_COORDINATE void Transformation::reset() { -#if !ENABLE_WORLD_COORDINATE - m_offset = Vec3d::Zero(); - m_rotation = Vec3d::Zero(); - m_scaling_factor = Vec3d::Ones(); - m_mirror = Vec3d::Ones(); -#endif // !ENABLE_WORLD_COORDINATE m_matrix = Transform3d::Identity(); -#if !ENABLE_WORLD_COORDINATE - m_dirty = false; -#endif // !ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE void Transformation::reset_rotation() { const Geometry::TransformationSVD svd(*this); @@ -755,88 +622,12 @@ Transform3d Transformation::get_matrix_no_scaling_factor() const copy.reset_scaling_factor(); return copy.get_matrix(); } -#else -const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const -{ - if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror)) { - m_matrix = Geometry::assemble_transform( - dont_translate ? Vec3d::Zero() : m_offset, - dont_rotate ? Vec3d::Zero() : m_rotation, - dont_scale ? Vec3d::Ones() : m_scaling_factor, - dont_mirror ? Vec3d::Ones() : m_mirror - ); - - m_flags.set(dont_translate, dont_rotate, dont_scale, dont_mirror); - m_dirty = false; - } - - return m_matrix; -} -#endif // ENABLE_WORLD_COORDINATE Transformation Transformation::operator * (const Transformation& other) const { return Transformation(get_matrix() * other.get_matrix()); } -#if !ENABLE_WORLD_COORDINATE -Transformation Transformation::volume_to_bed_transformation(const Transformation& instance_transformation, const BoundingBoxf3& bbox) -{ - Transformation out; - - if (instance_transformation.is_scaling_uniform()) { - // No need to run the non-linear least squares fitting for uniform scaling. - // Just set the inverse. - out.set_from_transform(instance_transformation.get_matrix(true).inverse()); - } - else if (is_rotation_ninety_degrees(instance_transformation.get_rotation())) { - // Anisotropic scaling, rotation by multiples of ninety degrees. - Eigen::Matrix3d instance_rotation_trafo = - (Eigen::AngleAxisd(instance_transformation.get_rotation().z(), Vec3d::UnitZ()) * - Eigen::AngleAxisd(instance_transformation.get_rotation().y(), Vec3d::UnitY()) * - Eigen::AngleAxisd(instance_transformation.get_rotation().x(), Vec3d::UnitX())).toRotationMatrix(); - Eigen::Matrix3d volume_rotation_trafo = - (Eigen::AngleAxisd(-instance_transformation.get_rotation().x(), Vec3d::UnitX()) * - Eigen::AngleAxisd(-instance_transformation.get_rotation().y(), Vec3d::UnitY()) * - Eigen::AngleAxisd(-instance_transformation.get_rotation().z(), Vec3d::UnitZ())).toRotationMatrix(); - - // 8 corners of the bounding box. - auto pts = Eigen::MatrixXd(8, 3); - pts(0, 0) = bbox.min.x(); pts(0, 1) = bbox.min.y(); pts(0, 2) = bbox.min.z(); - pts(1, 0) = bbox.min.x(); pts(1, 1) = bbox.min.y(); pts(1, 2) = bbox.max.z(); - pts(2, 0) = bbox.min.x(); pts(2, 1) = bbox.max.y(); pts(2, 2) = bbox.min.z(); - pts(3, 0) = bbox.min.x(); pts(3, 1) = bbox.max.y(); pts(3, 2) = bbox.max.z(); - pts(4, 0) = bbox.max.x(); pts(4, 1) = bbox.min.y(); pts(4, 2) = bbox.min.z(); - pts(5, 0) = bbox.max.x(); pts(5, 1) = bbox.min.y(); pts(5, 2) = bbox.max.z(); - pts(6, 0) = bbox.max.x(); pts(6, 1) = bbox.max.y(); pts(6, 2) = bbox.min.z(); - pts(7, 0) = bbox.max.x(); pts(7, 1) = bbox.max.y(); pts(7, 2) = bbox.max.z(); - - // Corners of the bounding box transformed into the modifier mesh coordinate space, with inverse rotation applied to the modifier. - auto qs = pts * - (instance_rotation_trafo * - Eigen::Scaling(instance_transformation.get_scaling_factor().cwiseProduct(instance_transformation.get_mirror())) * - volume_rotation_trafo).inverse().transpose(); - // Fill in scaling based on least squares fitting of the bounding box corners. - Vec3d scale; - for (int i = 0; i < 3; ++i) - scale(i) = pts.col(i).dot(qs.col(i)) / pts.col(i).dot(pts.col(i)); - - out.set_rotation(Geometry::extract_rotation(volume_rotation_trafo)); - out.set_scaling_factor(Vec3d(std::abs(scale.x()), std::abs(scale.y()), std::abs(scale.z()))); - out.set_mirror(Vec3d(scale.x() > 0 ? 1. : -1, scale.y() > 0 ? 1. : -1, scale.z() > 0 ? 1. : -1)); - } - else { - // General anisotropic scaling, general rotation. - // Keep the modifier mesh in the instance coordinate system, so the modifier mesh will not be aligned with the world. - // Scale it to get the required size. - out.set_scaling_factor(instance_transformation.get_scaling_factor().cwiseInverse()); - } - - return out; -} -#endif // !ENABLE_WORLD_COORDINATE - -#if ENABLE_WORLD_COORDINATE TransformationSVD::TransformationSVD(const Transform3d& trafo) { const auto &m0 = trafo.matrix().block<3, 3>(0, 0); @@ -883,7 +674,6 @@ TransformationSVD::TransformationSVD(const Transform3d& trafo) } else skew = false; } -#endif // ENABLE_WORLD_COORDINATE // For parsing a transformation matrix from 3MF / AMF. Transform3d transform3d_from_string(const std::string& transform_str) diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index ba7e7a4b2..c410a57f2 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -383,32 +383,9 @@ Vec3d extract_rotation(const Transform3d& transform); class Transformation { -#if ENABLE_WORLD_COORDINATE Transform3d m_matrix{ Transform3d::Identity() }; -#else - struct Flags - { - bool dont_translate{ true }; - bool dont_rotate{ true }; - bool dont_scale{ true }; - bool dont_mirror{ true }; - - bool needs_update(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const; - void set(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror); - }; - - Vec3d m_offset{ Vec3d::Zero() }; // In unscaled coordinates - Vec3d m_rotation{ Vec3d::Zero() }; // Rotation around the three axes, in radians around mesh center point - Vec3d m_scaling_factor{ Vec3d::Ones() }; // Scaling factors along the three axes - Vec3d m_mirror{ Vec3d::Ones() }; // Mirroring along the three axes - - mutable Transform3d m_matrix{ Transform3d::Identity() }; - mutable Flags m_flags; - mutable bool m_dirty{ false }; -#endif // ENABLE_WORLD_COORDINATE public: -#if ENABLE_WORLD_COORDINATE Transformation() = default; explicit Transformation(const Transform3d& transform) : m_matrix(transform) {} @@ -424,26 +401,10 @@ public: double get_rotation(Axis axis) const { return get_rotation()[axis]; } Transform3d get_rotation_matrix() const; -#else - Transformation(); - explicit Transformation(const Transform3d& transform); - - const Vec3d& get_offset() const { return m_offset; } - double get_offset(Axis axis) const { return m_offset(axis); } - - void set_offset(const Vec3d& offset); - void set_offset(Axis axis, double offset); - - const Vec3d& get_rotation() const { return m_rotation; } - double get_rotation(Axis axis) const { return m_rotation(axis); } - - Transform3d get_rotation_matrix() const { return rotation_transform(get_rotation()); } -#endif // ENABLE_WORLD_COORDINATE void set_rotation(const Vec3d& rotation); void set_rotation(Axis axis, double rotation); -#if ENABLE_WORLD_COORDINATE Vec3d get_scaling_factor() const; double get_scaling_factor(Axis axis) const { return get_scaling_factor()[axis]; } @@ -453,17 +414,10 @@ public: const Vec3d scale = get_scaling_factor(); return std::abs(scale.x() - scale.y()) < 1e-8 && std::abs(scale.x() - scale.z()) < 1e-8; } -#else - const Vec3d& get_scaling_factor() const { return m_scaling_factor; } - double get_scaling_factor(Axis axis) const { return m_scaling_factor(axis); } - - Transform3d get_scaling_factor_matrix() const { return scale_transform(get_scaling_factor()); } -#endif // ENABLE_WORLD_COORDINATE void set_scaling_factor(const Vec3d& scaling_factor); void set_scaling_factor(Axis axis, double scaling_factor); -#if ENABLE_WORLD_COORDINATE Vec3d get_mirror() const; double get_mirror(Axis axis) const { return get_mirror()[axis]; } @@ -472,25 +426,13 @@ public: bool is_left_handed() const { return m_matrix.linear().determinant() < 0; } -#else - bool is_scaling_uniform() const { return std::abs(m_scaling_factor.x() - m_scaling_factor.y()) < 1e-8 && std::abs(m_scaling_factor.x() - m_scaling_factor.z()) < 1e-8; } - - const Vec3d& get_mirror() const { return m_mirror; } - double get_mirror(Axis axis) const { return m_mirror(axis); } - bool is_left_handed() const { return m_mirror.x() * m_mirror.y() * m_mirror.z() < 0.; } -#endif // ENABLE_WORLD_COORDINATE void set_mirror(const Vec3d& mirror); void set_mirror(Axis axis, double mirror); -#if ENABLE_WORLD_COORDINATE bool has_skew() const; -#else - void set_from_transform(const Transform3d& transform); -#endif // ENABLE_WORLD_COORDINATE void reset(); -#if ENABLE_WORLD_COORDINATE void reset_offset() { set_offset(Vec3d::Zero()); } void reset_rotation(); void reset_scaling_factor(); @@ -502,22 +444,11 @@ public: Transform3d get_matrix_no_scaling_factor() const; void set_matrix(const Transform3d& transform) { m_matrix = transform; } -#else - const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const; -#endif // ENABLE_WORLD_COORDINATE Transformation operator * (const Transformation& other) const; -#if !ENABLE_WORLD_COORDINATE - // Find volume transformation, so that the chained (instance_trafo * volume_trafo) will be as close to identity - // as possible in least squares norm in regard to the 8 corners of bbox. - // Bounding box is expected to be centered around zero in all axes. - static Transformation volume_to_bed_transformation(const Transformation& instance_transformation, const BoundingBoxf3& bbox); -#endif // !ENABLE_WORLD_COORDINATE - private: friend class cereal::access; -#if ENABLE_WORLD_COORDINATE template void serialize(Archive& ar) { ar(m_matrix); } explicit Transformation(int) {} template static void load_and_construct(Archive& ar, cereal::construct& construct) @@ -526,24 +457,13 @@ private: construct(1); ar(construct.ptr()->m_matrix); } -#else - template void serialize(Archive& ar) { ar(m_offset, m_rotation, m_scaling_factor, m_mirror); } - explicit Transformation(int) : m_dirty(true) {} - template static void load_and_construct(Archive& ar, cereal::construct& construct) - { - // Calling a private constructor with special "int" parameter to indicate that no construction is necessary. - construct(1); - ar(construct.ptr()->m_offset, construct.ptr()->m_rotation, construct.ptr()->m_scaling_factor, construct.ptr()->m_mirror); - } -#endif // ENABLE_WORLD_COORDINATE }; -#if ENABLE_WORLD_COORDINATE struct TransformationSVD { - Matrix3d u = Matrix3d::Identity(); - Matrix3d s = Matrix3d::Identity(); - Matrix3d v = Matrix3d::Identity(); + Matrix3d u{ Matrix3d::Identity() }; + Matrix3d s{ Matrix3d::Identity() }; + Matrix3d v{ Matrix3d::Identity() }; bool mirror{ false }; bool scale{ false }; @@ -557,7 +477,6 @@ struct TransformationSVD Eigen::DiagonalMatrix mirror_matrix() const { return Eigen::DiagonalMatrix(this->mirror ? -1. : 1., 1., 1.); } }; -#endif // ENABLE_WORLD_COORDINATE // For parsing a transformation matrix from 3MF / AMF. extern Transform3d transform3d_from_string(const std::string& transform_str); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6fdec8b14..08e70964e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -1030,11 +1030,7 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const if (this->instances.empty()) throw Slic3r::InvalidArgument("Can't call raw_bounding_box() with no instances"); -#if ENABLE_WORLD_COORDINATE const Transform3d inst_matrix = this->instances.front()->get_transformation().get_matrix_no_offset(); -#else - const Transform3d& inst_matrix = this->instances.front()->get_transformation().get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE for (const ModelVolume *v : this->volumes) if (v->is_model_part()) m_raw_bounding_box.merge(v->mesh().transformed_bounding_box(inst_matrix * v->get_matrix())); @@ -1046,14 +1042,10 @@ const BoundingBoxf3& ModelObject::raw_bounding_box() const BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_translate) const { BoundingBoxf3 bb; -#if ENABLE_WORLD_COORDINATE const Transform3d inst_matrix = dont_translate ? this->instances[instance_idx]->get_transformation().get_matrix_no_offset() : this->instances[instance_idx]->get_transformation().get_matrix(); -#else - const Transform3d& inst_matrix = this->instances[instance_idx]->get_transformation().get_matrix(dont_translate); -#endif // ENABLE_WORLD_COORDINATE for (ModelVolume *v : this->volumes) { if (v->is_model_part()) bb.merge(v->mesh().transformed_bounding_box(inst_matrix * v->get_matrix())); @@ -1688,17 +1680,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, const Transform3d& cut_matrix, // in the transformation matrix and not applied to the mesh transform. // const auto instance_matrix = instances[instance]->get_matrix(true); -#if ENABLE_WORLD_COORDINATE const auto instance_matrix = instances[instance]->get_transformation().get_matrix_no_offset(); -#else - const auto instance_matrix = assemble_transform( - Vec3d::Zero(), // don't apply offset - instances[instance]->get_rotation(), - instances[instance]->get_scaling_factor(), - instances[instance]->get_mirror() - ); -#endif // ENABLE_WORLD_COORDINATE - const Transformation cut_transformation = Transformation(cut_matrix); const Transform3d inverse_cut_matrix = cut_transformation.get_rotation_matrix().inverse() * translation_transform(-1. * cut_transformation.get_offset()); @@ -1840,11 +1822,7 @@ void ModelObject::split(ModelObjectPtrs* new_objects) new_vol->config.set_key_value("extruder", new ConfigOptionInt(0)); for (ModelInstance* model_instance : new_object->instances) { -#if ENABLE_WORLD_COORDINATE - Vec3d shift = model_instance->get_transformation().get_matrix_no_offset() * new_vol->get_offset(); -#else - Vec3d shift = model_instance->get_transformation().get_matrix(true) * new_vol->get_offset(); -#endif // ENABLE_WORLD_COORDINATE + const Vec3d shift = model_instance->get_transformation().get_matrix_no_offset() * new_vol->get_offset(); model_instance->set_offset(model_instance->get_offset() + shift); } @@ -1885,13 +1863,7 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) { assert(instance_idx < this->instances.size()); - const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation(); -#if !ENABLE_WORLD_COORDINATE - if (Geometry::is_rotation_ninety_degrees(reference_trafo.get_rotation())) - // nothing to do, scaling in the world coordinate space is possible in the representation of Geometry::Transformation. - return; -#endif // !ENABLE_WORLD_COORDINATE - + const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation(); bool left_handed = reference_trafo.is_left_handed(); bool has_mirrorring = ! reference_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.)); bool uniform_scaling = std::abs(reference_trafo.get_scaling_factor().x() - reference_trafo.get_scaling_factor().y()) < EPSILON && @@ -1908,7 +1880,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) // Adjust the meshes. // Transformation to be applied to the meshes. -#if ENABLE_WORLD_COORDINATE Geometry::Transformation reference_trafo_mod = reference_trafo; reference_trafo_mod.reset_offset(); if (uniform_scaling) @@ -1916,9 +1887,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) if (!has_mirrorring) reference_trafo_mod.reset_mirror(); Eigen::Matrix3d mesh_trafo_3x3 = reference_trafo_mod.get_matrix().matrix().block<3, 3>(0, 0); -#else - Eigen::Matrix3d mesh_trafo_3x3 = reference_trafo.get_matrix(true, false, uniform_scaling, ! has_mirrorring).matrix().block<3, 3>(0, 0); -#endif // ENABLE_WORLD_COORDINATE Transform3d volume_offset_correction = this->instances[instance_idx]->get_transformation().get_matrix().inverse() * reference_trafo.get_matrix(); for (ModelVolume *model_volume : this->volumes) { const Geometry::Transformation volume_trafo = model_volume->get_transformation(); @@ -1928,7 +1896,6 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) std::abs(volume_trafo.get_scaling_factor().x() - volume_trafo.get_scaling_factor().z()) < EPSILON; double volume_new_scaling_factor = volume_uniform_scaling ? volume_trafo.get_scaling_factor().x() : 1.; // Transform the mesh. -#if ENABLE_WORLD_COORDINATE Geometry::Transformation volume_trafo_mod = volume_trafo; volume_trafo_mod.reset_offset(); if (volume_uniform_scaling) @@ -1936,11 +1903,8 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx) if (!volume_has_mirrorring) volume_trafo_mod.reset_mirror(); Eigen::Matrix3d volume_trafo_3x3 = volume_trafo_mod.get_matrix().matrix().block<3, 3>(0, 0); -#else - Matrix3d volume_trafo_3x3 = volume_trafo.get_matrix(true, false, volume_uniform_scaling, !volume_has_mirrorring).matrix().block<3, 3>(0, 0); -#endif // ENABLE_WORLD_COORDINATE // Following method creates a new shared_ptr - model_volume->transform_this_mesh(mesh_trafo_3x3 * volume_trafo_3x3, left_handed != volume_left_handed); + model_volume->transform_this_mesh(mesh_trafo_3x3 * volume_trafo_3x3, left_handed != volume_left_handed); // Reset the rotation, scaling and mirroring. model_volume->set_rotation(Vec3d(0., 0., 0.)); model_volume->set_scaling_factor(Vec3d(volume_new_scaling_factor, volume_new_scaling_factor, volume_new_scaling_factor)); @@ -1959,11 +1923,7 @@ double ModelObject::get_instance_min_z(size_t instance_idx) const double min_z = DBL_MAX; const ModelInstance* inst = instances[instance_idx]; -#if ENABLE_WORLD_COORDINATE const Transform3d mi = inst->get_matrix_no_offset(); -#else - const Transform3d& mi = inst->get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE for (const ModelVolume* v : volumes) { if (!v->is_model_part()) @@ -1984,11 +1944,7 @@ double ModelObject::get_instance_max_z(size_t instance_idx) const double max_z = -DBL_MAX; const ModelInstance* inst = instances[instance_idx]; -#if ENABLE_WORLD_COORDINATE const Transform3d mi = inst->get_matrix_no_offset(); -#else - const Transform3d& mi = inst->get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE for (const ModelVolume* v : volumes) { if (!v->is_model_part()) @@ -2428,29 +2384,17 @@ void ModelVolume::convert_from_meters() void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const { -#if ENABLE_WORLD_COORDINATE mesh->transform(dont_translate ? get_matrix_no_offset() : get_matrix()); -#else - mesh->transform(get_matrix(dont_translate)); -#endif // ENABLE_WORLD_COORDINATE } BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const { -#if ENABLE_WORLD_COORDINATE return bbox.transformed(dont_translate ? get_matrix_no_offset() : get_matrix()); -#else - return bbox.transformed(get_matrix(dont_translate)); -#endif // ENABLE_WORLD_COORDINATE } Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const { -#if ENABLE_WORLD_COORDINATE return dont_translate ? get_matrix_no_offset() * v : get_matrix() * v; -#else - return get_matrix(dont_translate) * v; -#endif // ENABLE_WORLD_COORDINATE } void ModelInstance::transform_polygon(Polygon* polygon) const diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 3fd9f21bc..60746f10b 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -881,26 +881,16 @@ public: const Geometry::Transformation& get_transformation() const { return m_transformation; } void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } -#if ENABLE_WORLD_COORDINATE void set_transformation(const Transform3d& trafo) { m_transformation.set_matrix(trafo); } Vec3d get_offset() const { return m_transformation.get_offset(); } -#else - void set_transformation(const Transform3d &trafo) { m_transformation.set_from_transform(trafo); } - - const Vec3d& get_offset() const { return m_transformation.get_offset(); } -#endif // ENABLE_WORLD_COORDINATE double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } -#if ENABLE_WORLD_COORDINATE Vec3d get_rotation() const { return m_transformation.get_rotation(); } -#else - const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } -#endif // ENABLE_WORLD_COORDINATE double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } @@ -912,11 +902,7 @@ public: void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } -#if ENABLE_WORLD_COORDINATE Vec3d get_mirror() const { return m_transformation.get_mirror(); } -#else - const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } -#endif // ENABLE_WORLD_COORDINATE double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } bool is_left_handed() const { return m_transformation.is_left_handed(); } @@ -925,12 +911,8 @@ public: void convert_from_imperial_units(); void convert_from_meters(); -#if ENABLE_WORLD_COORDINATE const Transform3d& get_matrix() const { return m_transformation.get_matrix(); } Transform3d get_matrix_no_offset() const { return m_transformation.get_matrix_no_offset(); } -#else - const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } -#endif // ENABLE_WORLD_COORDINATE void set_new_unique_id() { ObjectBase::set_new_unique_id(); @@ -1142,43 +1124,27 @@ public: const Geometry::Transformation& get_transformation() const { return m_transformation; } void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } -#if ENABLE_WORLD_COORDINATE Vec3d get_offset() const { return m_transformation.get_offset(); } -#else - const Vec3d& get_offset() const { return m_transformation.get_offset(); } -#endif // ENABLE_WORLD_COORDINATE double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } -#if ENABLE_WORLD_COORDINATE Vec3d get_rotation() const { return m_transformation.get_rotation(); } -#else - const Vec3d& get_rotation() const { return m_transformation.get_rotation(); } -#endif // ENABLE_WORLD_COORDINATE double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } -#if ENABLE_WORLD_COORDINATE Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } -#else - const Vec3d& get_scaling_factor() const { return m_transformation.get_scaling_factor(); } -#endif // ENABLE_WORLD_COORDINATE double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } -#if ENABLE_WORLD_COORDINATE Vec3d get_mirror() const { return m_transformation.get_mirror(); } -#else - const Vec3d& get_mirror() const { return m_transformation.get_mirror(); } -#endif // ENABLE_WORLD_COORDINATE double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } - bool is_left_handed() const { return m_transformation.is_left_handed(); } + bool is_left_handed() const { return m_transformation.is_left_handed(); } void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } @@ -1192,12 +1158,8 @@ public: // To be called on an external polygon. It does not translate the polygon, only rotates and scales. void transform_polygon(Polygon* polygon) const; -#if ENABLE_WORLD_COORDINATE const Transform3d& get_matrix() const { return m_transformation.get_matrix(); } Transform3d get_matrix_no_offset() const { return m_transformation.get_matrix_no_offset(); } -#else - const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const { return m_transformation.get_matrix(dont_translate, dont_rotate, dont_scale, dont_mirror); } -#endif // ENABLE_WORLD_COORDINATE bool is_printable() const { return object->printable && printable && (print_volume_state == ModelInstancePVS_Inside); } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 67407e591..14e77e03f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -396,7 +396,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly // FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2) // which causes that the warning will be showed after arrangement with the // appropriate object distance. Even if I set this to jtMiter the warning still shows up. -#if ENABLE_WORLD_COORDINATE Geometry::Transformation trafo = model_instance0->get_transformation(); trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() }); it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id, @@ -405,15 +404,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)), jtRound, scale_(0.1)).front()); -#else - it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id, - offset(print_object->model_object()->convex_hull_2d( - Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), model_instance0->get_scaling_factor(), model_instance0->get_mirror())), - // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects - // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. - float(scale_(0.5 * print.config().extruder_clearance_radius.value - BuildVolume::BedEpsilon)), - jtRound, scale_(0.1)).front()); -#endif // ENABLE_WORLD_COORDINATE } // Make a copy, so it may be rotated for instances. Polygon convex_hull0 = it_convex_hull->second; @@ -1347,11 +1337,23 @@ const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt) const { // If the wipe tower wasn't created yet, make sure the depth and brim_width members are set to default. if (! is_step_done(psWipeTower) && extruders_cnt !=0) { + const_cast(this)->m_wipe_tower_data.brim_width = m_config.wipe_tower_brim_width; + + // Calculating depth should take into account currently set wiping volumes. + // For a long time, the initial preview would just use 900/width per toolchange (15mm on a 60mm wide tower) + // and it worked well enough. Let's try to do slightly better by accounting for the purging volumes. + std::vector> wipe_volumes = WipeTower::extract_wipe_volumes(m_config); + std::vector max_wipe_volumes; + for (const std::vector& v : wipe_volumes) + max_wipe_volumes.emplace_back(*std::max_element(v.begin(), v.end())); + float maximum = std::accumulate(max_wipe_volumes.begin(), max_wipe_volumes.end(), 0.f); + maximum = maximum * extruders_cnt / max_wipe_volumes.size(); float width = float(m_config.wipe_tower_width); + float layer_height = 0.2f; // just assume fixed value, it will still be better than before. - const_cast(this)->m_wipe_tower_data.depth = (900.f/width) * float(extruders_cnt - 1); - const_cast(this)->m_wipe_tower_data.brim_width = m_config.wipe_tower_brim_width; + const_cast(this)->m_wipe_tower_data.depth = (maximum/layer_height)/width; + const_cast(this)->m_wipe_tower_data.height = -1.f; // unknown yet } return m_wipe_tower_data; @@ -1363,13 +1365,7 @@ void Print::_make_wipe_tower() if (! this->has_wipe_tower()) return; - // Get wiping matrix to get number of extruders and convert vector to vector: - std::vector wiping_matrix(cast(m_config.wiping_volumes_matrix.values)); - // Extract purging volumes for each extruder pair: - std::vector> wipe_volumes; - const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON); - for (unsigned int i = 0; i(wiping_matrix.begin()+i*number_of_extruders, wiping_matrix.begin()+(i+1)*number_of_extruders)); + std::vector> wipe_volumes = WipeTower::extract_wipe_volumes(m_config); // Let the ToolOrdering class know there will be initial priming extrusions at the start of the print. m_wipe_tower_data.tool_ordering = ToolOrdering(*this, (unsigned int)-1, true); @@ -1422,7 +1418,7 @@ void Print::_make_wipe_tower() //wipe_tower.set_zhop(); // Set the extruder & material properties at the wipe tower object. - for (size_t i = 0; i < number_of_extruders; ++ i) + for (size_t i = 0; i < m_config.nozzle_diameter.size(); ++ i) wipe_tower.set_extruder(i, m_config); m_wipe_tower_data.priming = Slic3r::make_unique>( diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index ae5f18fcb..1cd91a33a 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -791,13 +791,8 @@ void update_volume_bboxes( if (it != volumes_old.end() && it->volume_id == model_volume->id()) layer_range.volumes.emplace_back(*it); } else -#if ENABLE_WORLD_COORDINATE layer_range.volumes.push_back({ model_volume->id(), transformed_its_bbox2d(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix()), offset) }); -#else - layer_range.volumes.push_back({ model_volume->id(), - transformed_its_bbox2d(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix(false)), offset) }); -#endif // ENABLE_WORLD_COORDINATE } } else { std::vector> volumes_old; @@ -829,11 +824,7 @@ void update_volume_bboxes( layer_range.volumes.emplace_back(*it); } } else { -#if ENABLE_WORLD_COORDINATE transformed_its_bboxes_in_z_ranges(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix()), ranges, bboxes, offset); -#else - transformed_its_bboxes_in_z_ranges(model_volume->mesh().its, trafo_for_bbox(object_trafo, model_volume->get_matrix(false)), ranges, bboxes, offset); -#endif // ENABLE_WORLD_COORDINATE for (PrintObjectRegions::LayerRangeRegions &layer_range : layer_ranges) if (auto &bbox = bboxes[&layer_range - layer_ranges.data()]; bbox.second) layer_range.volumes.push_back({ model_volume->id(), bbox.first }); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2fb2b877a..fdf97cbe2 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4935,18 +4935,21 @@ std::string get_sla_suptree_prefix(const DynamicPrintConfig &config) return slatree; } -bool is_XL_printer(const DynamicPrintConfig &cfg) +static bool is_XL_printer(const std::string& printer_model) { static constexpr const char *ALIGN_ONLY_FOR = "XL"; + return boost::algorithm::contains(printer_model, ALIGN_ONLY_FOR); +} - bool ret = false; - +bool is_XL_printer(const DynamicPrintConfig &cfg) +{ auto *printer_model = cfg.opt("printer_model"); + return printer_model && is_XL_printer(printer_model->value); +} - if (printer_model) - ret = boost::algorithm::contains(printer_model->value, ALIGN_ONLY_FOR); - - return ret; +bool is_XL_printer(const PrintConfig &cfg) +{ + return is_XL_printer(cfg.printer_model.value); } } // namespace Slic3r diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 08f3bcd2f..06f0472ae 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1192,6 +1192,7 @@ private: }; bool is_XL_printer(const DynamicPrintConfig &cfg); +bool is_XL_printer(const PrintConfig &cfg); Points get_bed_shape(const DynamicPrintConfig &cfg); Points get_bed_shape(const PrintConfig &cfg); diff --git a/src/libslic3r/SLA/Rotfinder.cpp b/src/libslic3r/SLA/Rotfinder.cpp index ab98f3e93..5f25d5b60 100644 --- a/src/libslic3r/SLA/Rotfinder.cpp +++ b/src/libslic3r/SLA/Rotfinder.cpp @@ -300,18 +300,8 @@ struct RotfinderBoilerplate { TriangleMesh mesh = mo.raw_mesh(); ModelInstance *mi = mo.instances[0]; -#if ENABLE_WORLD_COORDINATE const Geometry::Transformation trafo = mi->get_transformation(); Transform3d trafo_instance = trafo.get_scaling_factor_matrix() * trafo.get_mirror_matrix(); -#else - auto rotation = Vec3d::Zero(); - auto offset = Vec3d::Zero(); - Transform3d trafo_instance = - Geometry::assemble_transform(offset, rotation, - mi->get_scaling_factor(), - mi->get_mirror()); -#endif // ENABLE_WORLD_COORDINATE - mesh.transform(trafo_instance); return mesh; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 791230d4e..c33f24311 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -32,6 +32,10 @@ #define ENABLE_RAYCAST_PICKING_DEBUG 0 // Shows an imgui dialog with GLModel statistics data #define ENABLE_GLMODEL_STATISTICS 0 +// Shows an imgui dialog containing the matrices of the selected volumes +#define ENABLE_MATRICES_DEBUG 0 +// Shows an imgui dialog containing data from class ObjectManipulation +#define ENABLE_OBJECT_MANIPULATION_DEBUG 0 // Enable rendering of objects using environment map @@ -39,24 +43,23 @@ // Enable smoothing of objects normals #define ENABLE_SMOOTH_NORMALS 0 - -//==================== -// 2.6.0.alpha1 techs -//==================== -#define ENABLE_2_6_0_ALPHA1 1 - // Enable OpenGL ES #define ENABLE_OPENGL_ES 0 // Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows) #define ENABLE_GL_CORE_PROFILE (1 && !ENABLE_OPENGL_ES) // Enable OpenGL debug messages using debug context #define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE) -// Enable editing volumes transformation in world coordinates and instances in local coordinates -#define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_6_0_ALPHA1) -// Shows an imgui dialog containing the matrices of the selected volumes -#define ENABLE_WORLD_COORDINATE_DEBUG (0 && ENABLE_WORLD_COORDINATE) + + +//==================== +// 2.6.0.alpha1 techs +//==================== +#define ENABLE_2_6_0_ALPHA1 1 + // Enable alternative version of file_wildcards() #define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_6_0_ALPHA1) +// Enable gcode postprocess modified to allow for backward insertion of new lines +#define ENABLE_GCODE_POSTPROCESS_BACKTRACE (1 && ENABLE_2_6_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index b4f0dd9d8..f43afdf42 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -29,54 +29,6 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0 namespace Slic3r { namespace GUI { -#if !ENABLE_WORLD_COORDINATE -const float Bed3D::Axes::DefaultStemRadius = 0.5f; -const float Bed3D::Axes::DefaultStemLength = 25.0f; -const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius; -const float Bed3D::Axes::DefaultTipLength = 5.0f; - -void Bed3D::Axes::render() -{ - auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) { - const Camera& camera = wxGetApp().plater()->get_camera(); - const Transform3d& view_matrix = camera.get_view_matrix(); - shader->set_uniform("view_model_matrix", view_matrix * transform); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); - const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * transform.matrix().block(0, 0, 3, 3).inverse().transpose(); - shader->set_uniform("view_normal_matrix", view_normal_matrix); - m_arrow.render(); - }; - - if (!m_arrow.is_initialized()) - m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length)); - - GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light"); - if (shader == nullptr) - return; - - glsafe(::glEnable(GL_DEPTH_TEST)); - - shader->start_using(); - shader->set_uniform("emission_factor", 0.0f); - - // x axis - m_arrow.set_color(ColorRGBA::X()); - render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 })); - - // y axis - m_arrow.set_color(ColorRGBA::Y()); - render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 })); - - // z axis - m_arrow.set_color(ColorRGBA::Z()); - render_axis(shader, Geometry::assemble_transform(m_origin)); - - shader->stop_using(); - - glsafe(::glDisable(GL_DEPTH_TEST)); -} -#endif // !ENABLE_WORLD_COORDINATE - bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) { auto check_texture = [](const std::string& texture) { @@ -201,11 +153,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const out.merge(m_axes.get_origin()); // extend to contain axes out.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones()); -#if ENABLE_WORLD_COORDINATE out.merge(out.min + Vec3d(-m_axes.get_tip_radius(), -m_axes.get_tip_radius(), out.max.z())); -#else - out.merge(out.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, out.max.z())); -#endif // ENABLE_WORLD_COORDINATE // extend to contain model, if any BoundingBoxf3 model_bb = m_model.model.get_bounding_box(); if (model_bb.defined) { @@ -364,11 +312,7 @@ std::tuple Bed3D::detect_type(const Point void Bed3D::render_axes() { if (m_build_volume.valid()) -#if ENABLE_WORLD_COORDINATE m_axes.render(Transform3d::Identity(), 0.25f); -#else - m_axes.render(); -#endif // ENABLE_WORLD_COORDINATE } void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture) diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 031a8e8a3..cf20b6a29 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -3,11 +3,7 @@ #include "GLTexture.hpp" #include "3DScene.hpp" -#if ENABLE_WORLD_COORDINATE #include "CoordAxes.hpp" -#else -#include "GLModel.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "MeshUtils.hpp" #include "libslic3r/BuildVolume.hpp" @@ -23,32 +19,6 @@ class GLCanvas3D; class Bed3D { -#if !ENABLE_WORLD_COORDINATE - class Axes - { - public: - static const float DefaultStemRadius; - static const float DefaultStemLength; - static const float DefaultTipRadius; - static const float DefaultTipLength; - - private: - Vec3d m_origin{ Vec3d::Zero() }; - float m_stem_length{ DefaultStemLength }; - GLModel m_arrow; - - public: - const Vec3d& get_origin() const { return m_origin; } - void set_origin(const Vec3d& origin) { m_origin = origin; } - void set_stem_length(float length) { - m_stem_length = length; - m_arrow.reset(); - } - float get_total_length() const { return m_stem_length + DefaultTipLength; } - void render(); - }; -#endif // !ENABLE_WORLD_COORDINATE - public: enum class Type : unsigned char { @@ -77,11 +47,7 @@ private: GLTexture m_temp_texture; PickingModel m_model; Vec3d m_model_offset{ Vec3d::Zero() }; -#if ENABLE_WORLD_COORDINATE CoordAxes m_axes; -#else - Axes m_axes; -#endif // ENABLE_WORLD_COORDINATE float m_scale_factor{ 1.0f }; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 71361e68f..97975404f 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -488,13 +488,11 @@ int GLVolumeCollection::load_wipe_tower_preview( float rotation_angle, bool size_unknown, float brim_width) #endif // ENABLE_OPENGL_ES { - if (depth < 0.01f) - return int(this->volumes.size() - 1); if (height == 0.0f) height = 0.1f; static const float brim_height = 0.2f; - const float scaled_brim_height = brim_height / height; +// const float scaled_brim_height = brim_height / height; TriangleMesh mesh; ColorRGBA color = ColorRGBA::DARK_YELLOW(); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index f9eb4f2d4..2f7e0a767 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -212,23 +212,15 @@ public: const Geometry::Transformation& get_instance_transformation() const { return m_instance_transformation; } void set_instance_transformation(const Geometry::Transformation& transformation) { m_instance_transformation = transformation; set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE void set_instance_transformation(const Transform3d& transform) { m_instance_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); } Vec3d get_instance_offset() const { return m_instance_transformation.get_offset(); } -#else - const Vec3d& get_instance_offset() const { return m_instance_transformation.get_offset(); } -#endif // ENABLE_WORLD_COORDINATE double get_instance_offset(Axis axis) const { return m_instance_transformation.get_offset(axis); } void set_instance_offset(const Vec3d& offset) { m_instance_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); } void set_instance_offset(Axis axis, double offset) { m_instance_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE Vec3d get_instance_rotation() const { return m_instance_transformation.get_rotation(); } -#else - const Vec3d& get_instance_rotation() const { return m_instance_transformation.get_rotation(); } -#endif // ENABLE_WORLD_COORDINATE double get_instance_rotation(Axis axis) const { return m_instance_transformation.get_rotation(axis); } void set_instance_rotation(const Vec3d& rotation) { m_instance_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); } @@ -240,11 +232,7 @@ public: void set_instance_scaling_factor(const Vec3d& scaling_factor) { m_instance_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); } void set_instance_scaling_factor(Axis axis, double scaling_factor) { m_instance_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE Vec3d get_instance_mirror() const { return m_instance_transformation.get_mirror(); } -#else - const Vec3d& get_instance_mirror() const { return m_instance_transformation.get_mirror(); } -#endif // ENABLE_WORLD_COORDINATE double get_instance_mirror(Axis axis) const { return m_instance_transformation.get_mirror(axis); } void set_instance_mirror(const Vec3d& mirror) { m_instance_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); } @@ -252,43 +240,27 @@ public: const Geometry::Transformation& get_volume_transformation() const { return m_volume_transformation; } void set_volume_transformation(const Geometry::Transformation& transformation) { m_volume_transformation = transformation; set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE void set_volume_transformation(const Transform3d& transform) { m_volume_transformation.set_matrix(transform); set_bounding_boxes_as_dirty(); } Vec3d get_volume_offset() const { return m_volume_transformation.get_offset(); } -#else - const Vec3d& get_volume_offset() const { return m_volume_transformation.get_offset(); } -#endif // ENABLE_WORLD_COORDINATE double get_volume_offset(Axis axis) const { return m_volume_transformation.get_offset(axis); } void set_volume_offset(const Vec3d& offset) { m_volume_transformation.set_offset(offset); set_bounding_boxes_as_dirty(); } void set_volume_offset(Axis axis, double offset) { m_volume_transformation.set_offset(axis, offset); set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE Vec3d get_volume_rotation() const { return m_volume_transformation.get_rotation(); } -#else - const Vec3d& get_volume_rotation() const { return m_volume_transformation.get_rotation(); } -#endif // ENABLE_WORLD_COORDINATE double get_volume_rotation(Axis axis) const { return m_volume_transformation.get_rotation(axis); } void set_volume_rotation(const Vec3d& rotation) { m_volume_transformation.set_rotation(rotation); set_bounding_boxes_as_dirty(); } void set_volume_rotation(Axis axis, double rotation) { m_volume_transformation.set_rotation(axis, rotation); set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE Vec3d get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); } -#else - const Vec3d& get_volume_scaling_factor() const { return m_volume_transformation.get_scaling_factor(); } -#endif // ENABLE_WORLD_COORDINATE double get_volume_scaling_factor(Axis axis) const { return m_volume_transformation.get_scaling_factor(axis); } void set_volume_scaling_factor(const Vec3d& scaling_factor) { m_volume_transformation.set_scaling_factor(scaling_factor); set_bounding_boxes_as_dirty(); } void set_volume_scaling_factor(Axis axis, double scaling_factor) { m_volume_transformation.set_scaling_factor(axis, scaling_factor); set_bounding_boxes_as_dirty(); } -#if ENABLE_WORLD_COORDINATE Vec3d get_volume_mirror() const { return m_volume_transformation.get_mirror(); } -#else - const Vec3d& get_volume_mirror() const { return m_volume_transformation.get_mirror(); } -#endif // ENABLE_WORLD_COORDINATE double get_volume_mirror(Axis axis) const { return m_volume_transformation.get_mirror(axis); } void set_volume_mirror(const Vec3d& mirror) { m_volume_transformation.set_mirror(mirror); set_bounding_boxes_as_dirty(); } diff --git a/src/slic3r/GUI/CoordAxes.cpp b/src/slic3r/GUI/CoordAxes.cpp index fcb434f3b..734f8ddfa 100644 --- a/src/slic3r/GUI/CoordAxes.cpp +++ b/src/slic3r/GUI/CoordAxes.cpp @@ -8,8 +8,6 @@ #include -#if ENABLE_WORLD_COORDINATE - namespace Slic3r { namespace GUI { @@ -69,5 +67,3 @@ void CoordAxes::render(const Transform3d& trafo, float emission_factor) } // GUI } // Slic3r - -#endif // ENABLE_WORLD_COORDINATE diff --git a/src/slic3r/GUI/CoordAxes.hpp b/src/slic3r/GUI/CoordAxes.hpp index 2679608a3..1d934751f 100644 --- a/src/slic3r/GUI/CoordAxes.hpp +++ b/src/slic3r/GUI/CoordAxes.hpp @@ -1,7 +1,6 @@ #ifndef slic3r_CoordAxes_hpp_ #define slic3r_CoordAxes_hpp_ -#if ENABLE_WORLD_COORDINATE #include "GLModel.hpp" namespace Slic3r { @@ -55,6 +54,4 @@ public: } // GUI } // Slic3r -#endif // ENABLE_WORLD_COORDINATE - #endif // slic3r_CoordAxes_hpp_ diff --git a/src/slic3r/GUI/Downloader.cpp b/src/slic3r/GUI/Downloader.cpp index 3d2a00106..ebf275b8f 100644 --- a/src/slic3r/GUI/Downloader.cpp +++ b/src/slic3r/GUI/Downloader.cpp @@ -147,7 +147,7 @@ void Downloader::start_download(const std::string& full_url) std::string escaped_url = FileGet::escape_url(full_url.substr(24)); #endif if (!boost::starts_with(escaped_url, "https://") || !FileGet::is_subdomain(escaped_url, "printables.com")) { - std::string msg = format(_L("Download won't start. Download URL doesn't point to https://files.printables.com : %1%"), escaped_url); + std::string msg = format(_L("Download won't start. Download URL doesn't point to https://printables.com : %1%"), escaped_url); BOOST_LOG_TRIVIAL(error) << msg; NotificationManager* ntf_mngr = wxGetApp().notification_manager(); ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, msg); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8e77d830b..f55f16bbc 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -954,9 +954,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent); -#if ENABLE_WORLD_COORDINATE wxDEFINE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent); -#endif // ENABLE_WORLD_COORDINATE wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); @@ -1641,6 +1639,9 @@ void GLCanvas3D::render() #if ENABLE_GLMODEL_STATISTICS GLModel::render_statistics(); #endif // ENABLE_GLMODEL_STATISTICS +#if ENABLE_OBJECT_MANIPULATION_DEBUG + wxGetApp().obj_manipul()->render_debug_window(); +#endif // ENABLE_OBJECT_MANIPULATION_DEBUG std::string tooltip; @@ -1816,7 +1817,6 @@ std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) void GLCanvas3D::mirror_selection(Axis axis) { -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (wxGetApp().obj_manipul()->is_local_coordinates()) transformation_type.set_local(); @@ -1827,9 +1827,7 @@ void GLCanvas3D::mirror_selection(Axis axis) m_selection.setup_cache(); m_selection.mirror(axis, transformation_type); -#else - m_selection.mirror(axis); -#endif // ENABLE_WORLD_COORDINATE + do_mirror(L("Mirror Object")); wxGetApp().obj_manipul()->set_dirty(); } @@ -2140,8 +2138,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re const bool co = dynamic_cast(m_config->option("complete_objects"))->value; if (extruders_count > 1 && wt && !co) { - // Height of a print (Show at least a slab) - const double height = std::max(m_model->max_z(), 10.0); const float x = dynamic_cast(m_config->option("wipe_tower_x"))->value; const float y = dynamic_cast(m_config->option("wipe_tower_y"))->value; @@ -2152,6 +2148,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re const Print *print = m_process->fff_print(); const float depth = print->wipe_tower_data(extruders_count).depth; + const float height_real = print->wipe_tower_data(extruders_count).height; // -1.f = unknown + + // Height of a print (Show at least a slab). + const double height = height_real < 0.f ? std::max(m_model->max_z(), 10.0) : height_real; #if ENABLE_OPENGL_ES int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( @@ -2724,13 +2724,9 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) else displacement = multiplier * direction; -#if ENABLE_WORLD_COORDINATE TransformationType trafo_type; trafo_type.set_relative(); m_selection.translate(displacement, trafo_type); -#else - m_selection.translate(displacement); -#endif // ENABLE_WORLD_COORDINATE m_dirty = true; } ); @@ -3337,14 +3333,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } -#if ENABLE_WORLD_COORDINATE m_moving = true; TransformationType trafo_type; trafo_type.set_relative(); m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type); -#else - m_selection.translate(cur_pos - m_mouse.drag.start_position_3D); -#endif // ENABLE_WORLD_COORDINATE if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects) update_sequential_clearance(); wxGetApp().obj_manipul()->set_dirty(); @@ -3612,17 +3604,9 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { if (selection_mode == Selection::Instance) -#if ENABLE_WORLD_COORDINATE model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); -#else - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); -#endif // ENABLE_WORLD_COORDINATE else if (selection_mode == Selection::Volume) -#if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); -#else - model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); -#endif // ENABLE_WORLD_COORDINATE object_moved = true; model_object->invalidate_bounding_box(); @@ -3693,13 +3677,9 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) for (const GLVolume* v : m_volumes.volumes) { if (v->is_wipe_tower) { const Vec3d offset = v->get_volume_offset(); -#if ENABLE_WORLD_COORDINATE Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX(); double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x()); post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot))); -#else - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); -#endif // ENABLE_WORLD_COORDINATE } const int object_idx = v->object_idx(); if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) @@ -3716,22 +3696,10 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) // Rotate instances/volumes. ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { - if (selection_mode == Selection::Instance) { -#if ENABLE_WORLD_COORDINATE + if (selection_mode == Selection::Instance) model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); -#else - model_object->instances[instance_idx]->set_rotation(v->get_instance_rotation()); - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); -#endif // ENABLE_WORLD_COORDINATE - } - else if (selection_mode == Selection::Volume) { -#if ENABLE_WORLD_COORDINATE + else if (selection_mode == Selection::Volume) model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); -#else - model_object->volumes[volume_idx]->set_rotation(v->get_volume_rotation()); - model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); -#endif // ENABLE_WORLD_COORDINATE - } model_object->invalidate_bounding_box(); } } @@ -3795,23 +3763,11 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) // Rotate instances/volumes ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { - if (selection_mode == Selection::Instance) { -#if ENABLE_WORLD_COORDINATE + if (selection_mode == Selection::Instance) model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); -#else - model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor()); - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); -#endif // ENABLE_WORLD_COORDINATE - } else if (selection_mode == Selection::Volume) { -#if ENABLE_WORLD_COORDINATE model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); -#else - model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); - model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor()); - model_object->volumes[volume_idx]->set_offset(v->get_volume_offset()); -#endif // ENABLE_WORLD_COORDINATE } model_object->invalidate_bounding_box(); } @@ -3873,18 +3829,9 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type) ModelObject* model_object = m_model->objects[object_idx]; if (model_object != nullptr) { if (selection_mode == Selection::Instance) -#if ENABLE_WORLD_COORDINATE model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation()); -#else - model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror()); -#endif // ENABLE_WORLD_COORDINATE else if (selection_mode == Selection::Volume) -#if ENABLE_WORLD_COORDINATE model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation()); -#else - model_object->volumes[volume_idx]->set_mirror(v->get_volume_mirror()); -#endif // ENABLE_WORLD_COORDINATE - model_object->invalidate_bounding_box(); } } @@ -3907,7 +3854,6 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type) m_dirty = true; } -#if ENABLE_WORLD_COORDINATE void GLCanvas3D::do_reset_skew(const std::string& snapshot_type) { if (m_model == nullptr) @@ -3969,7 +3915,6 @@ void GLCanvas3D::do_reset_skew(const std::string& snapshot_type) m_dirty = true; } -#endif // ENABLE_WORLD_COORDINATE void GLCanvas3D::update_gizmos_on_off_state() { @@ -4148,7 +4093,6 @@ void GLCanvas3D::update_sequential_clearance() for (size_t i = 0; i < m_model->objects.size(); ++i) { ModelObject* model_object = m_model->objects[i]; ModelInstance* model_instance0 = model_object->instances.front(); -#if ENABLE_WORLD_COORDINATE Geometry::Transformation trafo = model_instance0->get_transformation(); trafo.set_offset({ 0.0, 0.0, model_instance0->get_offset().z() }); const Polygon hull_2d = offset(model_object->convex_hull_2d(trafo.get_matrix()), @@ -4156,14 +4100,6 @@ void GLCanvas3D::update_sequential_clearance() // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. shrink_factor, jtRound, mitter_limit).front(); -#else - Polygon hull_2d = offset(model_object->convex_hull_2d(Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), - model_instance0->get_scaling_factor(), model_instance0->get_mirror())), - // Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects - // exactly by satisfying the extruder_clearance_radius, this test will not trigger collision. - shrink_factor, - jtRound, mitter_limit).front(); -#endif // ENABLE_WORLD_COORDINATE Pointf3s& cache_hull_2d = m_sequential_print_clearance.m_hull_2d_cache.emplace_back(Pointf3s()); cache_hull_2d.reserve(hull_2d.points.size()); @@ -5750,9 +5686,9 @@ void GLCanvas3D::_render_selection() if (!m_gizmos.is_running()) m_selection.render(scale_factor); -#if ENABLE_WORLD_COORDINATE_DEBUG +#if ENABLE_MATRICES_DEBUG m_selection.render_debug_window(); -#endif // ENABLE_WORLD_COORDINATE_DEBUG +#endif // ENABLE_MATRICES_DEBUG } void GLCanvas3D::_render_sequential_clearance() @@ -6168,18 +6104,11 @@ void GLCanvas3D::_render_sla_slices() for (const SLAPrintObject::Instance& inst : obj->instances()) { const Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_WORLD_COORDINATE Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::translation_transform({ unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0 }) * Geometry::rotation_transform(inst.rotation * Vec3d::UnitZ()); if (obj->is_left_handed()) view_model_matrix = view_model_matrix * Geometry::scale_transform({ -1.0f, 1.0f, 1.0f }); -#else - const Transform3d view_model_matrix = camera.get_view_matrix() * - Geometry::assemble_transform(Vec3d(unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0), - inst.rotation * Vec3d::UnitZ(), Vec3d::Ones(), - obj->is_left_handed() ? /* The polygons are mirrored by X */ Vec3d(-1.0f, 1.0f, 1.0f) : Vec3d::Ones()); -#endif // ENABLE_WORLD_COORDINATE shader->set_uniform("view_model_matrix", view_model_matrix); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); @@ -7330,11 +7259,10 @@ const ModelVolume *get_model_volume(const GLVolume &v, const Model &model) { const ModelVolume * ret = nullptr; - if (v.object_idx() < model.objects.size()) { + if (v.object_idx() < (int)model.objects.size()) { const ModelObject *obj = model.objects[v.object_idx()]; - if (v.volume_idx() < obj->volumes.size()) { + if (v.volume_idx() < (int)obj->volumes.size()) ret = obj->volumes[v.volume_idx()]; - } } return ret; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a79bcff2e..0f45d0597 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -157,9 +157,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent); -#if ENABLE_WORLD_COORDINATE wxDECLARE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent); -#endif // ENABLE_WORLD_COORDINATE wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event); @@ -771,11 +769,7 @@ public: void update_volumes_colors_by_extruder(); -#if ENABLE_WORLD_COORDINATE bool is_dragging() const { return m_gizmos.is_dragging() || (m_moving && !m_mouse.scene_position.isApprox(m_mouse.drag.start_position_3D)); } -#else - bool is_dragging() const { return m_gizmos.is_dragging() || m_moving; } -#endif // ENABLE_WORLD_COORDINATE void render(); // printable_only == false -> render also non printable volumes as grayed @@ -845,9 +839,7 @@ public: void do_rotate(const std::string& snapshot_type); void do_scale(const std::string& snapshot_type); void do_mirror(const std::string& snapshot_type); -#if ENABLE_WORLD_COORDINATE void do_reset_skew(const std::string& snapshot_type); -#endif // ENABLE_WORLD_COORDINATE void update_gizmos_on_off_state(); void reset_all_gizmos() { m_gizmos.reset_all_states(); } diff --git a/src/slic3r/GUI/GUI_Geometry.hpp b/src/slic3r/GUI/GUI_Geometry.hpp index 0d6cf7f4b..b18e4ae5a 100644 --- a/src/slic3r/GUI/GUI_Geometry.hpp +++ b/src/slic3r/GUI/GUI_Geometry.hpp @@ -4,7 +4,6 @@ namespace Slic3r { namespace GUI { -#if ENABLE_WORLD_COORDINATE enum class ECoordinatesType : unsigned char { World, @@ -73,8 +72,6 @@ private: Enum m_value; }; -#endif // ENABLE_WORLD_COORDINATE - } // namespace Slic3r } // namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 5f8b9a75b..863729fc4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1603,11 +1603,7 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo // First (any) GLVolume of the selected instance. They all share the same instance matrix. const GLVolume* v = selection.get_first_volume(); const Geometry::Transformation inst_transform = v->get_instance_transformation(); -#if ENABLE_WORLD_COORDINATE const Transform3d inv_inst_transform = inst_transform.get_matrix_no_offset().inverse(); -#else - const Transform3d inv_inst_transform = inst_transform.get_matrix(true).inverse(); -#endif // ENABLE_WORLD_COORDINATE const Vec3d instance_offset = v->get_instance_offset(); for (size_t i = 0; i < input_files.size(); ++i) { @@ -1655,15 +1651,9 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo new_volume->source.mesh_offset = model.objects.front()->volumes.front()->source.mesh_offset; if (from_galery) { -#if ENABLE_WORLD_COORDINATE // Transform the new modifier to be aligned with the print bed. new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse()); const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box(); -#else - // Transform the new modifier to be aligned with the print bed. - const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box(); - new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(inst_transform, mesh_bb)); -#endif // ENABLE_WORLD_COORDINATE // Set the modifier position. // Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed. const Vec3d offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - instance_offset; @@ -1732,15 +1722,9 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode // First (any) GLVolume of the selected instance. They all share the same instance matrix. const GLVolume* v = selection.get_first_volume(); -#if ENABLE_WORLD_COORDINATE // Transform the new modifier to be aligned with the print bed. new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse()); const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box(); -#else - // Transform the new modifier to be aligned with the print bed. - const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box(); - new_volume->set_transformation(Geometry::Transformation::volume_to_bed_transformation(v->get_instance_transformation(), mesh_bb)); -#endif // ENABLE_WORLD_COORDINATE // Set the modifier position. Vec3d offset; if (type_name == "Slab") { @@ -1752,11 +1736,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode // Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed. offset = Vec3d(instance_bb.max.x(), instance_bb.min.y(), instance_bb.min.z()) + 0.5 * mesh_bb.size() - v->get_instance_offset(); } -#if ENABLE_WORLD_COORDINATE new_volume->set_offset(v->get_instance_transformation().get_matrix_no_offset().inverse() * offset); -#else - new_volume->set_offset(v->get_instance_transformation().get_matrix(true).inverse() * offset); -#endif // ENABLE_WORLD_COORDINATE const wxString name = _L("Generic") + "-" + _(type_name); new_volume->name = into_u8(name); @@ -2687,6 +2667,8 @@ void ObjectList::part_selection_changed() bool disable_ss_manipulation {false}; bool disable_ununiform_scale {false}; + ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); + const auto item = GetSelection(); GLGizmosManager& gizmos_mgr = wxGetApp().plater()->canvas3D()->get_gizmos_manager(); @@ -2703,6 +2685,7 @@ void ObjectList::part_selection_changed() if (selection.is_single_full_object()) { og_name = _L("Object manipulation"); + coordinates_type = ECoordinatesType::World; update_and_show_manipulations = true; obj_idx = selection.get_object_idx(); @@ -2712,6 +2695,7 @@ void ObjectList::part_selection_changed() } else { og_name = _L("Group manipulation"); + coordinates_type = ECoordinatesType::World; // don't show manipulation panel for case of all Object's parts selection update_and_show_manipulations = !selection.is_single_full_instance(); @@ -2767,6 +2751,8 @@ void ObjectList::part_selection_changed() || type == itInfo) { og_name = _L("Object manipulation"); m_config = &object->config; + if (!scene_selection().is_single_full_instance() || coordinates_type > ECoordinatesType::Instance) + coordinates_type = ECoordinatesType::World; update_and_show_manipulations = true; if (type == itInfo) { @@ -2844,6 +2830,8 @@ void ObjectList::part_selection_changed() if (update_and_show_manipulations) { wxGetApp().obj_manipul()->get_og()->set_name(" " + og_name + " "); + if (wxGetApp().obj_manipul()->get_coordinates_type() != coordinates_type) + wxGetApp().obj_manipul()->set_coordinates_type(coordinates_type); if (item) { wxGetApp().obj_manipul()->update_item_name(m_objects_model->GetName(item)); @@ -2875,7 +2863,6 @@ void ObjectList::part_selection_changed() Sidebar& panel = wxGetApp().sidebar(); panel.Freeze(); -#if ENABLE_WORLD_COORDINATE std::string opt_key; if (m_selected_object_id >= 0) { const ManipulationEditor* const editor = wxGetApp().obj_manipul()->get_focused_editor(); @@ -2883,9 +2870,6 @@ void ObjectList::part_selection_changed() opt_key = editor->get_full_opt_name(); } wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, !opt_key.empty()); -#else - wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); -#endif // ENABLE_WORLD_COORDINATE wxGetApp().plater()->canvas3D()->enable_moving(enable_manipulation); // ysFIXME wxGetApp().obj_manipul() ->UpdateAndShow(update_and_show_manipulations); wxGetApp().obj_settings()->UpdateAndShow(update_and_show_settings); @@ -3714,11 +3698,7 @@ void ObjectList::update_selections() return; sels.Add(m_objects_model->GetItemById(selection.get_object_idx())); } -#if ENABLE_WORLD_COORDINATE else if (selection.is_single_volume_or_modifier()) { -#else - else if (selection.is_single_volume() || selection.is_any_modifier()) { -#endif // ENABLE_WORLD_COORDINATE const auto gl_vol = selection.get_first_volume(); if (m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item)) == gl_vol->volume_idx()) return; diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 02ef719f1..7c8df40b3 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -53,17 +53,10 @@ static choice_ctrl* create_word_local_combo(wxWindow *parent) temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); if (!wxOSX) temp->SetBackgroundStyle(wxBG_STYLE_PAINT); -#if ENABLE_WORLD_COORDINATE temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::World)); temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Instance)); temp->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Local)); temp->Select((int)ECoordinatesType::World); -#else - temp->Append(_L("World coordinates")); - temp->Append(_L("Local coordinates")); - temp->SetSelection(0); - temp->SetValue(temp->GetString(0)); -#endif // ENABLE_WORLD_COORDINATE temp->SetToolTip(_L("Select coordinate space, in which the transformation will be performed.")); return temp; @@ -89,14 +82,9 @@ void msw_rescale_word_local_combo(choice_ctrl* combo) // Set rescaled size combo->SetSize(size); -#if ENABLE_WORLD_COORDINATE combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::World)); combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Instance)); combo->Append(ObjectManipulation::coordinate_type_str(ECoordinatesType::Local)); -#else - combo->Append(_L("World coordinates")); - combo->Append(_L("Local coordinates")); -#endif // ENABLE_WORLD_COORDINATE combo->SetValue(selection); #else @@ -126,10 +114,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Load bitmaps to be used for the mirroring buttons: m_mirror_bitmap_on = ScalableBitmap(parent, "mirroring_on"); -#if !ENABLE_WORLD_COORDINATE - m_mirror_bitmap_off = ScalableBitmap(parent, "mirroring_off"); - m_mirror_bitmap_hidden = ScalableBitmap(parent, "mirroring_transparent"); -#endif // !ENABLE_WORLD_COORDINATE const int border = wxOSX ? 0 : 4; const int em = wxGetApp().em_unit(); @@ -173,13 +157,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Add world local combobox m_word_local_combo = create_word_local_combo(parent); - m_word_local_combo->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent& evt) { -#if ENABLE_WORLD_COORDINATE - this->set_coordinates_type(evt.GetString()); -#else - this->set_world_coordinates(evt.GetSelection() != 1); -#endif // ENABLE_WORLD_COORDINATE - }), m_word_local_combo->GetId()); + m_word_local_combo->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent& evt) { this->set_coordinates_type(evt.GetString()); }), m_word_local_combo->GetId()); // Small trick to correct layouting in different view_mode : // Show empty string of a same height as a m_word_local_combo, when m_word_local_combo is hidden @@ -236,11 +214,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : add_label(&m_scale_Label, L("Scale"), v_sizer); wxStaticText* size_Label {nullptr}; -#if ENABLE_WORLD_COORDINATE add_label(&size_Label, L("Size [World]"), v_sizer); -#else - add_label(&size_Label, L("Size"), v_sizer); -#endif // ENABLE_WORLD_COORDINATE if (wxOSX) set_font_and_background_style(size_Label, wxGetApp().normal_font()); sizer->Add(v_sizer, 0, wxLEFT, border); @@ -272,31 +246,15 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // We will add a button to toggle mirroring to each axis: auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); -#if ENABLE_WORLD_COORDINATE btn->SetToolTip(format_wxstr(_L("Mirror along %1% axis"), label)); m_mirror_buttons[axis_idx] = btn; -#else - btn->SetToolTip(format_wxstr(_L("Toggle %1% axis mirroring"), label)); - btn->SetBitmapDisabled_(m_mirror_bitmap_hidden); - - m_mirror_buttons[axis_idx].first = btn; - m_mirror_buttons[axis_idx].second = mbShown; -#endif // ENABLE_WORLD_COORDINATE sizer->AddStretchSpacer(2); sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL); btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) { -#if !ENABLE_WORLD_COORDINATE - Axis axis = (Axis)(axis_idx + X); - if (m_mirror_buttons[axis_idx].second == mbHidden) - return; -#endif // !ENABLE_WORLD_COORDINATE - GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); - -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (is_local_coordinates()) transformation_type.set_local(); @@ -307,24 +265,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : selection.setup_cache(); selection.mirror((Axis)axis_idx, transformation_type); -#else - if (selection.is_single_volume() || selection.is_single_modifier()) { - GLVolume* volume = const_cast(selection.get_first_volume()); - volume->set_volume_mirror(axis, -volume->get_volume_mirror(axis)); - } - else if (selection.is_single_full_instance()) { - for (unsigned int idx : selection.get_volume_idxs()) { - GLVolume* volume = const_cast(selection.get_volume(idx)); - volume->set_instance_mirror(axis, -volume->get_instance_mirror(axis)); - } - } - else - return; - // Update mirroring at the GLVolumes. - selection.synchronize_unselected_instances(Selection::SyncRotationType::GENERAL); - selection.synchronize_unselected_volumes(); -#endif // ENABLE_WORLD_COORDINATE // Copy mirroring values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. canvas->do_mirror(L("Set Mirror")); UpdateAndShow(true); @@ -333,12 +274,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : editors_grid_sizer->Add(sizer, 0, wxALIGN_CENTER_HORIZONTAL); } -#if ENABLE_WORLD_COORDINATE m_mirror_warning_bitmap = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap); editors_grid_sizer->Add(m_mirror_warning_bitmap, 0, wxALIGN_CENTER_VERTICAL); -#else - editors_grid_sizer->AddStretchSpacer(1); -#endif // ENABLE_WORLD_COORDINATE editors_grid_sizer->AddStretchSpacer(1); // add EditBoxes @@ -377,7 +314,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); -#if ENABLE_WORLD_COORDINATE if (selection.is_single_volume_or_modifier()) { const GLVolume* volume = selection.get_first_volume(); const double min_z = get_volume_min_z(*volume); @@ -393,19 +329,8 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed")); change_position_value(2, m_cache.position.z() - min_z); } -#else - if (selection.is_single_volume() || selection.is_single_modifier()) { - const GLVolume* volume = selection.get_first_volume(); - const Vec3d diff = m_cache.position - volume->get_instance_transformation().get_matrix(true).inverse() * (get_volume_min_z(*volume) * Vec3d::UnitZ()); - - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed")); - change_position_value(0, diff.x()); - change_position_value(1, diff.y()); - change_position_value(2, diff.z()); -#endif // ENABLE_WORLD_COORDINATE } else if (selection.is_single_full_instance()) { -#if ENABLE_WORLD_COORDINATE const double min_z = selection.get_scaled_instance_bounding_box().min.z(); if (!is_world_coordinates()) { const GLVolume* volume = selection.get_first_volume(); @@ -417,20 +342,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : change_position_value(2, diff.z()); } else { -#else - const ModelObjectPtrs& objects = wxGetApp().model().objects; - const int idx = selection.get_object_idx(); - if (0 <= idx && idx < static_cast(objects.size())) { - const ModelObject* mo = wxGetApp().model().objects[idx]; - const double min_z = mo->bounding_box().min.z(); - if (std::abs(min_z) > SINKING_Z_THRESHOLD) { -#endif // ENABLE_WORLD_COORDINATE - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed")); - change_position_value(2, m_cache.position.z() - min_z); - } -#if !ENABLE_WORLD_COORDINATE + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Drop to bed")); + change_position_value(2, m_cache.position.z() - min_z); } -#endif // !ENABLE_WORLD_COORDINATE } }); editors_grid_sizer->Add(m_drop_to_bed_button); @@ -447,17 +361,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); selection.setup_cache(); -#if ENABLE_WORLD_COORDINATE if (selection.is_single_volume_or_modifier()) { GLVolume* vol = const_cast(selection.get_first_volume()); Geometry::Transformation trafo = vol->get_volume_transformation(); trafo.reset_rotation(); vol->set_volume_transformation(trafo); } -#else - if (selection.is_single_volume() || selection.is_single_modifier()) - const_cast(selection.get_first_volume())->set_volume_rotation(Vec3d::Zero()); -#endif // ENABLE_WORLD_COORDINATE else if (selection.is_single_full_instance()) { Geometry::Transformation trafo = selection.get_first_volume()->get_instance_transformation(); trafo.reset_rotation(); @@ -489,7 +398,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : m_reset_scale_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); m_reset_scale_button->SetToolTip(_L("Reset scale")); m_reset_scale_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) { -#if ENABLE_WORLD_COORDINATE GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); selection.setup_cache(); @@ -515,12 +423,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : canvas->do_scale(L("Reset scale")); UpdateAndShow(true); -#else - Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset scale")); - change_scale_value(0, 100.); - change_scale_value(1, 100.); - change_scale_value(2, 100.); -#endif // ENABLE_WORLD_COORDINATE }); editors_grid_sizer->Add(m_reset_scale_button); @@ -531,8 +433,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : m_main_grid_sizer->Add(editors_grid_sizer, 1, wxEXPAND); -#if ENABLE_WORLD_COORDINATE - m_skew_label = new wxStaticText(parent, wxID_ANY, _L("Skew")); + m_skew_label = new wxStaticText(parent, wxID_ANY, _L("Skew [World]")); m_main_grid_sizer->Add(m_skew_label, 1, wxEXPAND); m_reset_skew_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo")); @@ -548,7 +449,6 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : } }); m_main_grid_sizer->Add(m_reset_skew_button); -#endif // ENABLE_WORLD_COORDINATE m_check_inch = new wxCheckBox(parent, wxID_ANY, _L("Inches")); m_check_inch->SetFont(wxGetApp().normal_font()); @@ -568,9 +468,9 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : void ObjectManipulation::Show(const bool show) { - if (show != IsShown()) { - // Show all lines of the panel. Some of these lines will be hidden in the lines below. - m_og->Show(show); + if (show != IsShown()) { + // Show all lines of the panel. Some of these lines will be hidden in the lines below. + m_og->Show(show); if (show && wxGetApp().get_mode() != comSimple) { // Show the label and the name of the STL in simple mode only. @@ -581,9 +481,10 @@ void ObjectManipulation::Show(const bool show) } } - if (show) { - // Show the "World Coordinates" / "Local Coordintes" Combo in Advanced / Expert mode only. -#if ENABLE_WORLD_COORDINATE + if (show) { + ECoordinatesType coordinates_type = m_coordinates_type; + + // Show the "World Coordinates" / "Local Coordintes" Combo in Advanced / Expert mode only. const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); bool show_world_local_combo = wxGetApp().get_mode() != comSimple && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()); if (selection.is_single_volume_or_modifier() && m_word_local_combo->GetCount() < 3) { @@ -592,20 +493,15 @@ void ObjectManipulation::Show(const bool show) #else m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), wxNullBitmap, 2); #endif // __linux__ - m_word_local_combo->Select((int)ECoordinatesType::World); - this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection())); } else if (selection.is_single_full_instance() && m_word_local_combo->GetCount() > 2) { m_word_local_combo->Delete(2); - m_word_local_combo->Select((int)ECoordinatesType::World); - this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection())); + if (coordinates_type > ECoordinatesType::Instance) + coordinates_type = ECoordinatesType::World; } -#else - bool show_world_local_combo = wxGetApp().plater()->canvas3D()->get_selection().is_single_full_instance() && wxGetApp().get_mode() != comSimple; -#endif // ENABLE_WORLD_COORDINATE m_word_local_combo->Show(show_world_local_combo); m_empty_str->Show(!show_world_local_combo); - } + } } bool ObjectManipulation::IsShown() @@ -628,10 +524,7 @@ void ObjectManipulation::Enable(const bool enadle) for (auto editor : m_editors) editor->Enable(enadle); for (wxWindow* win : std::initializer_list{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt -#if ENABLE_WORLD_COORDINATE - ,m_reset_skew_button -#endif // ENABLE_WORLD_COORDINATE - }) + , m_reset_skew_button }) win->Enable(enadle); } @@ -639,11 +532,7 @@ void ObjectManipulation::DisableScale() { for (auto editor : m_editors) editor->Enable(editor->has_opt_key("scale") || editor->has_opt_key("size") ? false : true); - for (wxWindow* win : std::initializer_list{ m_reset_scale_button, m_lock_bnt -#if ENABLE_WORLD_COORDINATE - ,m_reset_skew_button -#endif // ENABLE_WORLD_COORDINATE - }) + for (wxWindow* win : std::initializer_list{ m_reset_scale_button, m_lock_bnt, m_reset_skew_button }) win->Enable(false); } @@ -717,52 +606,24 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_rotate_label_string = L("Rotation"); m_new_scale_label_string = L("Scale factors"); -#if !ENABLE_WORLD_COORDINATE - if (wxGetApp().get_mode() == comSimple) - m_world_coordinates = true; -#endif // !ENABLE_WORLD_COORDINATE - ObjectList* obj_list = wxGetApp().obj_list(); if (selection.is_single_full_instance()) { // all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one const GLVolume* volume = selection.get_first_volume(); -#if !ENABLE_WORLD_COORDINATE - m_new_position = volume->get_instance_offset(); - // Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible. - if (m_world_coordinates && ! m_uniform_scale && - ! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) { - // Manipulating an instance in the world coordinate system, rotation is not multiples of ninety degrees, therefore enforce uniform scaling. - m_uniform_scale = true; - m_lock_bnt->SetLock(true); - } -#endif // !ENABLE_WORLD_COORDINATE - -#if ENABLE_WORLD_COORDINATE if (is_world_coordinates()) { m_new_position = volume->get_instance_offset(); m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; m_new_rotate_label_string = L("Rotate (relative)"); -#else - if (m_world_coordinates) { - m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; - m_new_size = selection.get_scaled_instance_bounding_box().size(); - m_new_rotate_label_string = L("Rotate"); -#endif // ENABLE_WORLD_COORDINATE m_new_rotation = Vec3d::Zero(); } else { -#if ENABLE_WORLD_COORDINATE m_new_move_label_string = L("Translate (relative) [World]"); m_new_rotate_label_string = L("Rotate (relative)"); m_new_position = Vec3d::Zero(); m_new_rotation = Vec3d::Zero(); m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); -#else - m_new_rotation = volume->get_instance_rotation() * (180.0 / M_PI); - m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); -#endif // ENABLE_WORLD_COORDINATE m_new_scale = m_new_size.cwiseQuotient(selection.get_full_unscaled_instance_local_bounding_box().size()) * 100.0; } @@ -773,23 +634,14 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_position = box.center(); m_new_rotation = Vec3d::Zero(); m_new_scale = Vec3d(100.0, 100.0, 100.0); -#if ENABLE_WORLD_COORDINATE m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); -#else - m_new_size = box.size(); -#endif // ENABLE_WORLD_COORDINATE m_new_rotate_label_string = L("Rotate"); m_new_scale_label_string = L("Scale"); m_new_enabled = true; } -#if ENABLE_WORLD_COORDINATE else if (selection.is_single_volume_or_modifier()) { -#else - else if (selection.is_single_modifier() || selection.is_single_volume()) { -#endif // ENABLE_WORLD_COORDINATE // the selection contains a single volume const GLVolume* volume = selection.get_first_volume(); -#if ENABLE_WORLD_COORDINATE if (is_world_coordinates()) { const Geometry::Transformation trafo(volume->world_matrix()); @@ -811,23 +663,13 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); } else { -#endif // ENABLE_WORLD_COORDINATE m_new_position = volume->get_volume_offset(); -#if ENABLE_WORLD_COORDINATE m_new_rotate_label_string = L("Rotate (relative)"); -#else - m_new_rotate_label_string = L("Rotate"); -#endif // ENABLE_WORLD_COORDINATE m_new_rotation = Vec3d::Zero(); -#if ENABLE_WORLD_COORDINATE m_new_scale_label_string = L("Scale"); m_new_scale = Vec3d(100.0, 100.0, 100.0); m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); } -#else - m_new_scale = volume->get_volume_scaling_factor() * 100.0; - m_new_size = volume->get_instance_scaling_factor().cwiseProduct(volume->get_volume_scaling_factor().cwiseProduct(volume->bounding_box().size())); -#endif // ENABLE_WORLD_COORDINATE m_new_enabled = true; } else if (obj_list->is_connectors_item_selected() || obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) { @@ -835,11 +677,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_move_label_string = L("Translate"); m_new_rotate_label_string = L("Rotate"); m_new_scale_label_string = L("Scale"); -#if ENABLE_WORLD_COORDINATE m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); -#else - m_new_size = selection.get_bounding_box().size(); -#endif // ENABLE_WORLD_COORDINATE m_new_enabled = true; } } @@ -900,29 +738,9 @@ void ObjectManipulation::update_if_dirty() update(m_cache.rotation, m_cache.rotation_rounded, meRotation, m_new_rotation); } -#if !ENABLE_WORLD_COORDINATE - if (selection.requires_uniform_scale()) { - m_lock_bnt->SetLock(true); - m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection")); - m_lock_bnt->disable(); - } - else { -#endif // !ENABLE_WORLD_COORDINATE - m_lock_bnt->SetLock(m_uniform_scale); - m_lock_bnt->SetToolTip(wxEmptyString); - m_lock_bnt->enable(); -#if ENABLE_WORLD_COORDINATE - if (m_word_local_combo->GetSelection() != (int)m_coordinates_type) - m_word_local_combo->SetSelection((int)m_coordinates_type); -#else - } - - { - int new_selection = m_world_coordinates ? 0 : 1; - if (m_word_local_combo->GetSelection() != new_selection) - m_word_local_combo->SetSelection(new_selection); - } -#endif // ENABLE_WORLD_COORDINATE + m_lock_bnt->SetLock(m_uniform_scale); + m_lock_bnt->SetToolTip(wxEmptyString); + m_lock_bnt->enable(); if (m_new_enabled) m_og->enable(); @@ -937,9 +755,6 @@ void ObjectManipulation::update_if_dirty() m_dirty = false; } - - -#if ENABLE_WORLD_COORDINATE void ObjectManipulation::update_reset_buttons_visibility() { GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); @@ -965,7 +780,7 @@ void ObjectManipulation::update_reset_buttons_visibility() show_rotation = trafo_svd.rotation; show_scale = trafo_svd.scale; show_mirror = trafo_svd.mirror; - show_skew = trafo_svd.skew; + show_skew = Geometry::TransformationSVD(volume->world_matrix()).skew; } wxGetApp().CallAfter([this, show_drop_to_bed, show_rotation, show_scale, show_mirror, show_skew] { @@ -991,109 +806,13 @@ void ObjectManipulation::update_reset_buttons_visibility() } }); } -#else -void ObjectManipulation::update_reset_buttons_visibility() -{ - GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); - if (!canvas) - return; - const Selection& selection = canvas->get_selection(); - - bool show_rotation = false; - bool show_scale = false; - bool show_drop_to_bed = false; - if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { - const GLVolume* volume = selection.get_first_volume(); - Vec3d rotation; - Vec3d scale; - double min_z = 0.0; - - if (selection.is_single_full_instance()) { - rotation = volume->get_instance_rotation(); - scale = volume->get_instance_scaling_factor(); - min_z = selection.get_scaled_instance_bounding_box().min.z(); - } - else { - rotation = volume->get_volume_rotation(); - scale = volume->get_volume_scaling_factor(); - min_z = get_volume_min_z(*volume); - } - show_rotation = !rotation.isApprox(Vec3d::Zero()); - show_scale = !scale.isApprox(Vec3d::Ones()); - show_drop_to_bed = std::abs(min_z) > SINKING_Z_THRESHOLD; - } - - wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed] { - // There is a case (under OSX), when this function is called after the Manipulation panel is hidden - // So, let check if Manipulation panel is still shown for this moment - if (!this->IsShown()) - return; - m_reset_rotation_button->Show(show_rotation); - m_reset_scale_button->Show(show_scale); - m_drop_to_bed_button->Show(show_drop_to_bed); - - // Because of CallAfter we need to layout sidebar after Show/hide of reset buttons one more time - Sidebar& panel = wxGetApp().sidebar(); - if (!panel.IsFrozen()) { - panel.Freeze(); - panel.Layout(); - panel.Thaw(); - } - }); -} -#endif // ENABLE_WORLD_COORDINATE - - void ObjectManipulation::update_mirror_buttons_visibility() { -#if ENABLE_WORLD_COORDINATE const bool can_mirror = wxGetApp().plater()->can_mirror(); for (ScalableButton* button : m_mirror_buttons) { button->Enable(can_mirror); } -#else - GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); - Selection& selection = canvas->get_selection(); - - std::array new_states = { mbHidden, mbHidden, mbHidden }; - - if (!m_world_coordinates) { - if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { - const GLVolume* volume = selection.get_first_volume(); - Vec3d mirror; - - if (selection.is_single_full_instance()) - mirror = volume->get_instance_mirror(); - else - mirror = volume->get_volume_mirror(); - - for (unsigned char i=0; i<3; ++i) - new_states[i] = (mirror[i] < 0. ? mbActive : mbShown); - } - } - else { - // the mirroring buttons should be hidden in world coordinates, - // unless we make it actually mirror in world coords. - } - - // Hiding the buttons through Hide() always messed up the sizers. As a workaround, the button - // is assigned a transparent bitmap. We must of course remember the actual state. - wxGetApp().CallAfter([this, new_states]{ - for (int i=0; i<3; ++i) { - if (new_states[i] != m_mirror_buttons[i].second) { - const ScalableBitmap* bmp = nullptr; - switch (new_states[i]) { - case mbHidden : bmp = &m_mirror_bitmap_hidden; m_mirror_buttons[i].first->Enable(false); break; - case mbShown : bmp = &m_mirror_bitmap_off; m_mirror_buttons[i].first->Enable(true); break; - case mbActive : bmp = &m_mirror_bitmap_on; m_mirror_buttons[i].first->Enable(true); break; - } - m_mirror_buttons[i].first->SetBitmap_(*bmp); - m_mirror_buttons[i].second = new_states[i]; - } - } - }); -#endif // ENABLE_WORLD_COORDINATE } @@ -1125,7 +844,6 @@ void ObjectManipulation::update_warning_icon_state(const MeshErrorsInfo& warning m_fix_throught_netfab_bitmap->SetToolTip(tooltip); } -#if ENABLE_WORLD_COORDINATE wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type) { switch (type) @@ -1136,7 +854,19 @@ wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type) default: { assert(false); return _L("Unknown"); } } } -#endif // ENABLE_WORLD_COORDINATE + +#if ENABLE_OBJECT_MANIPULATION_DEBUG +void ObjectManipulation::render_debug_window() +{ + ImGuiWrapper& imgui = *wxGetApp().imgui(); +// ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once); + imgui.begin(std::string("ObjectManipulation"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize); + imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, "Coordinates type"); + ImGui::SameLine(); + imgui.text(coordinate_type_str(m_coordinates_type)); + imgui.end(); +} +#endif // ENABLE_OBJECT_MANIPULATION_DEBUG void ObjectManipulation::reset_settings_value() { @@ -1161,7 +891,6 @@ void ObjectManipulation::change_position_value(int axis, double value) auto canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); selection.setup_cache(); -#if ENABLE_WORLD_COORDINATE TransformationType trafo_type; trafo_type.set_relative(); switch (get_coordinates_type()) @@ -1171,9 +900,6 @@ void ObjectManipulation::change_position_value(int axis, double value) default: { break; } } selection.translate(position - m_cache.position, trafo_type); -#else - selection.translate(position - m_cache.position, selection.requires_local_axes()); -#endif // ENABLE_WORLD_COORDINATE canvas->do_move(L("Set Position")); m_cache.position = position; @@ -1192,7 +918,6 @@ void ObjectManipulation::change_rotation_value(int axis, double value) GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; transformation_type.set_relative(); if (selection.is_single_full_instance()) @@ -1203,16 +928,6 @@ void ObjectManipulation::change_rotation_value(int axis, double value) if (is_instance_coordinates()) transformation_type.set_instance(); -#else - TransformationType transformation_type(TransformationType::World_Relative_Joint); - if (selection.is_single_full_instance() || selection.requires_local_axes()) - transformation_type.set_independent(); - if (selection.is_single_full_instance() && ! m_world_coordinates) { - //FIXME Selection::rotate() does not process absoulte rotations correctly: It does not recognize the axis index, which was changed. - // transformation_type.set_absolute(); - transformation_type.set_local(); - } -#endif // ENABLE_WORLD_COORDINATE selection.setup_cache(); selection.rotate( @@ -1236,7 +951,6 @@ void ObjectManipulation::change_scale_value(int axis, double value) Vec3d scale = m_cache.scale; scale(axis) = value; -#if ENABLE_WORLD_COORDINATE const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); Vec3d ref_scale = m_cache.scale; if (selection.is_single_volume_or_modifier()) { @@ -1247,9 +961,6 @@ void ObjectManipulation::change_scale_value(int axis, double value) ref_scale = 100.0 * Vec3d::Ones(); this->do_scale(axis, scale.cwiseQuotient(ref_scale)); -#else - this->do_scale(axis, 0.01 * scale); -#endif // ENABLE_WORLD_COORDINATE m_cache.scale = scale; m_cache.scale_rounded(axis) = DBL_MAX; @@ -1278,39 +989,18 @@ void ObjectManipulation::change_size_value(int axis, double value) const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); Vec3d ref_size = m_cache.size; -#if ENABLE_WORLD_COORDINATE if (selection.is_single_volume_or_modifier()) { size = size.cwiseQuotient(ref_size); ref_size = Vec3d::Ones(); -#else - if (selection.is_single_volume() || selection.is_single_modifier()) { - const GLVolume* v = selection.get_first_volume(); - const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); - const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); - const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); - - size = local_change.cwiseProduct(v->get_volume_scaling_factor()); - ref_size = Vec3d::Ones(); -#endif // ENABLE_WORLD_COORDINATE } else if (selection.is_single_full_instance()) { -#if ENABLE_WORLD_COORDINATE if (is_world_coordinates()) ref_size = selection.get_full_unscaled_instance_bounding_box().size(); else ref_size = selection.get_full_unscaled_instance_local_bounding_box().size(); -#else - ref_size = m_world_coordinates ? - selection.get_unscaled_instance_bounding_box().size() : - wxGetApp().model().objects[selection.get_first_volume()->object_idx()]->raw_mesh_bounding_box().size(); -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE this->do_size(axis, size.cwiseQuotient(ref_size)); -#else - this->do_scale(axis, size.cwiseQuotient(ref_size)); -#endif // ENABLE_WORLD_COORDINATE m_cache.size = size; m_cache.size_rounded(axis) = DBL_MAX; @@ -1319,40 +1009,22 @@ void ObjectManipulation::change_size_value(int axis, double value) void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const { - Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); -#if !ENABLE_WORLD_COORDINATE - Vec3d scaling_factor = scale; -#endif // !ENABLE_WORLD_COORDINATE - -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (is_local_coordinates()) transformation_type.set_local(); else if (is_instance_coordinates()) transformation_type.set_instance(); + Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); if (selection.is_single_volume_or_modifier() && !is_local_coordinates()) transformation_type.set_relative(); const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale; -#else - TransformationType transformation_type(TransformationType::World_Relative_Joint); - if (selection.is_single_full_instance()) { - transformation_type.set_absolute(); - if (! m_world_coordinates) - transformation_type.set_local(); - } - - if (m_uniform_scale || selection.requires_uniform_scale()) - scaling_factor = scale(axis) * Vec3d::Ones(); -#endif // ENABLE_WORLD_COORDINATE - selection.setup_cache(); selection.scale(scaling_factor, transformation_type); wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale")); } -#if ENABLE_WORLD_COORDINATE void ObjectManipulation::do_size(int axis, const Vec3d& scale) const { Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); @@ -1368,7 +1040,6 @@ void ObjectManipulation::do_size(int axis, const Vec3d& scale) const selection.scale(scaling_factor, transformation_type); wxGetApp().plater()->canvas3D()->do_scale(L("Set Size")); } -#endif // ENABLE_WORLD_COORDINATE void ObjectManipulation::on_change(const std::string& opt_key, int axis, double new_value) { @@ -1407,51 +1078,14 @@ void ObjectManipulation::on_change(const std::string& opt_key, int axis, double void ObjectManipulation::set_uniform_scaling(const bool use_uniform_scale) { -#if ENABLE_WORLD_COORDINATE if (!use_uniform_scale) // Recalculate cached values at this panel, refresh the screen. this->UpdateAndShow(true); m_uniform_scale = use_uniform_scale; - set_dirty(); -#else - const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); - if (selection.is_single_full_instance() && m_world_coordinates && !use_uniform_scale) { - // Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible. - // all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one - const GLVolume* volume = selection.get_first_volume(); - // Is the angle close to a multiple of 90 degrees? - if (!Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) { - // Cannot apply scaling in the world coordinate system. - //wxMessageDialog dlg(GUI::wxGetApp().mainframe, - MessageDialog dlg(GUI::wxGetApp().mainframe, - _L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n" - "Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n" - "once the rotation is embedded into the object coordinates.") + "\n" + - _L("This operation is irreversible.\n" - "Do you want to proceed?"), - SLIC3R_APP_NAME, - wxYES_NO | wxCANCEL | wxCANCEL_DEFAULT | wxICON_QUESTION); - if (dlg.ShowModal() != wxID_YES) { - // Enforce uniform scaling. - m_lock_bnt->SetLock(true); - return; - } - // Bake the rotation into the meshes of the object. - wxGetApp().model().objects[volume->composite_id.object_id]->bake_xy_rotation_into_meshes(volume->composite_id.instance_id); - // Update the 3D scene, selections etc. - wxGetApp().plater()->update(); - // Recalculate cached values at this panel, refresh the screen. - this->UpdateAndShow(true); - } - } - - m_uniform_scale = use_uniform_scale; -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE void ObjectManipulation::set_coordinates_type(ECoordinatesType type) { if (wxGetApp().get_mode() == comSimple) @@ -1461,6 +1095,7 @@ void ObjectManipulation::set_coordinates_type(ECoordinatesType type) return; m_coordinates_type = type; + m_word_local_combo->SetSelection((int)m_coordinates_type); this->UpdateAndShow(true); GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); canvas->get_gizmos_manager().update_data(); @@ -1470,13 +1105,8 @@ void ObjectManipulation::set_coordinates_type(ECoordinatesType type) ECoordinatesType ObjectManipulation::get_coordinates_type() const { - const wxString og_name = get_og()->get_name(); - if (og_name.Contains(_L("Group manipulation"))) - return ECoordinatesType::World; - return m_coordinates_type; } -#endif // ENABLE_WORLD_COORDINATE void ObjectManipulation::msw_rescale() { @@ -1517,37 +1147,25 @@ void ObjectManipulation::sys_color_changed() editor->sys_color_changed(this); m_mirror_bitmap_on.sys_color_changed(); -#if !ENABLE_WORLD_COORDINATE - m_mirror_bitmap_off.sys_color_changed(); - m_mirror_bitmap_hidden.sys_color_changed(); -#endif // !ENABLE_WORLD_COORDINATE m_reset_scale_button->sys_color_changed(); m_reset_rotation_button->sys_color_changed(); m_drop_to_bed_button->sys_color_changed(); m_lock_bnt->sys_color_changed(); -#if ENABLE_WORLD_COORDINATE for (int id = 0; id < 3; ++id) { m_mirror_buttons[id]->sys_color_changed(); } -#else - for (int id = 0; id < 3; ++id) - m_mirror_buttons[id].first->sys_color_changed(); -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE void ObjectManipulation::set_coordinates_type(const wxString& type_string) { - ECoordinatesType type = ECoordinatesType::World; - if (type_string == coordinate_type_str(ECoordinatesType::Instance)) - type = ECoordinatesType::Instance; - else if (type_string == coordinate_type_str(ECoordinatesType::Local)) - type = ECoordinatesType::Local; - - this->set_coordinates_type(type); + if (type_string == coordinate_type_str(ECoordinatesType::Instance)) + this->set_coordinates_type(ECoordinatesType::Instance); + else if (type_string == coordinate_type_str(ECoordinatesType::Local)) + this->set_coordinates_type(ECoordinatesType::Local); + else + this->set_coordinates_type(ECoordinatesType::World); } -#endif // ENABLE_WORLD_COORDINATE static const char axes[] = { 'x', 'y', 'z' }; ManipulationEditor::ManipulationEditor(ObjectManipulation* parent, diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 69022dde7..428ffc24b 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -5,9 +5,7 @@ #include "GUI_ObjectSettings.hpp" #include "GUI_ObjectList.hpp" -#if ENABLE_WORLD_COORDINATE #include "GUI_Geometry.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "libslic3r/Point.hpp" #include @@ -60,9 +58,7 @@ public: void set_value(const wxString& new_value); void kill_focus(ObjectManipulation *parent); -#if ENABLE_WORLD_COORDINATE const std::string& get_full_opt_name() const { return m_full_opt_name; } -#endif // ENABLE_WORLD_COORDINATE bool has_opt_key(const std::string& key) { return m_opt_key == key; } @@ -125,31 +121,15 @@ private: // Non-owning pointers to the reset buttons, so we can hide and show them. ScalableButton* m_reset_scale_button{ nullptr }; ScalableButton* m_reset_rotation_button{ nullptr }; -#if ENABLE_WORLD_COORDINATE ScalableButton* m_reset_skew_button{ nullptr }; -#endif // ENABLE_WORLD_COORDINATE ScalableButton* m_drop_to_bed_button{ nullptr }; wxCheckBox* m_check_inch {nullptr}; -#if ENABLE_WORLD_COORDINATE std::array m_mirror_buttons; -#else - // Mirroring buttons and their current state - enum MirrorButtonState { - mbHidden, - mbShown, - mbActive - }; - std::array, 3> m_mirror_buttons; -#endif // ENABLE_WORLD_COORDINATE // Bitmaps for the mirroring buttons. ScalableBitmap m_mirror_bitmap_on; -#if !ENABLE_WORLD_COORDINATE - ScalableBitmap m_mirror_bitmap_off; - ScalableBitmap m_mirror_bitmap_hidden; -#endif // !ENABLE_WORLD_COORDINATE // Needs to be updated from OnIdle? bool m_dirty = false; @@ -163,37 +143,21 @@ private: Vec3d m_new_size; bool m_new_enabled {true}; bool m_uniform_scale {true}; -#if ENABLE_WORLD_COORDINATE ECoordinatesType m_coordinates_type{ ECoordinatesType::World }; -#else - // Does the object manipulation panel work in World or Local coordinates? - bool m_world_coordinates = true; -#endif // ENABLE_WORLD_COORDINATE LockButton* m_lock_bnt{ nullptr }; choice_ctrl* m_word_local_combo { nullptr }; ScalableBitmap m_manifold_warning_bmp; wxStaticBitmap* m_fix_throught_netfab_bitmap{ nullptr }; -#if ENABLE_WORLD_COORDINATE wxStaticBitmap* m_mirror_warning_bitmap{ nullptr }; -#endif // ENABLE_WORLD_COORDINATE -#if ENABLE_WORLD_COORDINATE // Currently focused editor (nullptr if none) ManipulationEditor* m_focused_editor{ nullptr }; -#else -#ifndef __APPLE__ - // Currently focused editor (nullptr if none) - ManipulationEditor* m_focused_editor {nullptr}; -#endif // __APPLE__ -#endif // ENABLE_WORLD_COORDINATE wxFlexGridSizer* m_main_grid_sizer; wxFlexGridSizer* m_labels_grid_sizer; -#if ENABLE_WORLD_COORDINATE wxStaticText* m_skew_label{ nullptr }; -#endif // ENABLE_WORLD_COORDINATE // sizers, used for msw_rescale wxBoxSizer* m_word_local_combo_sizer; @@ -221,17 +185,12 @@ public: void set_uniform_scaling(const bool use_uniform_scale); bool get_uniform_scaling() const { return m_uniform_scale; } -#if ENABLE_WORLD_COORDINATE + void set_coordinates_type(ECoordinatesType type); ECoordinatesType get_coordinates_type() const; bool is_world_coordinates() const { return m_coordinates_type == ECoordinatesType::World; } bool is_instance_coordinates() const { return m_coordinates_type == ECoordinatesType::Instance; } bool is_local_coordinates() const { return m_coordinates_type == ECoordinatesType::Local; } -#else - // Does the object manipulation panel work in World or Local coordinates? - void set_world_coordinates(const bool world_coordinates) { m_world_coordinates = world_coordinates; this->UpdateAndShow(true); } - bool get_world_coordinates() const { return m_world_coordinates; } -#endif // ENABLE_WORLD_COORDINATE void reset_cache() { m_cache.reset(); } #ifndef __APPLE__ @@ -247,22 +206,16 @@ public: void sys_color_changed(); void on_change(const std::string& opt_key, int axis, double new_value); void set_focused_editor(ManipulationEditor* focused_editor) { -#if ENABLE_WORLD_COORDINATE m_focused_editor = focused_editor; -#else -#ifndef __APPLE__ - m_focused_editor = focused_editor; -#endif // __APPLE__ -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE ManipulationEditor* get_focused_editor() { return m_focused_editor; } -#endif // ENABLE_WORLD_COORDINATE -#if ENABLE_WORLD_COORDINATE static wxString coordinate_type_str(ECoordinatesType type); -#endif // ENABLE_WORLD_COORDINATE + +#if ENABLE_OBJECT_MANIPULATION_DEBUG + void render_debug_window(); +#endif // ENABLE_OBJECT_MANIPULATION_DEBUG private: void reset_settings_value(); @@ -279,11 +232,9 @@ private: void change_scale_value(int axis, double value); void change_size_value(int axis, double value); void do_scale(int axis, const Vec3d &scale) const; -#if ENABLE_WORLD_COORDINATE void do_size(int axis, const Vec3d& scale) const; void set_coordinates_type(const wxString& type_string); -#endif // ENABLE_WORLD_COORDINATE }; }} diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 770c3ac41..eacc6be91 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -268,39 +268,13 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) { return true; } else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) { -#if ENABLE_WORLD_COORDINATE do_stop_dragging(is_leaving); -#else - for (auto &grabber : m_grabbers) grabber.dragging = false; - m_dragging = false; - - // NOTE: This should be part of GLCanvas3D - // Reset hover_id when leave window - if (is_leaving) m_parent.mouse_up_cleanup(); - - on_stop_dragging(); - - // There is prediction that after draggign, data are changed - // Data are updated twice also by canvas3D::reload_scene. - // Should be fixed. - m_parent.get_gizmos_manager().update_data(); - - wxGetApp().obj_manipul()->set_dirty(); - - // Let the plater know that the dragging finished, so a delayed - // refresh of the scene with the background processing data should - // be performed. - m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED)); - // updates camera target constraints - m_parent.refresh_camera_scene_box(); -#endif // ENABLE_WORLD_COORDINATE return true; } } return false; } -#if ENABLE_WORLD_COORDINATE void GLGizmoBase::do_stop_dragging(bool perform_mouse_cleanup) { for (auto& grabber : m_grabbers) grabber.dragging = false; @@ -326,7 +300,6 @@ void GLGizmoBase::do_stop_dragging(bool perform_mouse_cleanup) // updates camera target constraints m_parent.refresh_camera_scene_box(); } -#endif // ENABLE_WORLD_COORDINATE std::string GLGizmoBase::format(float value, unsigned int decimals) const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp index 9ed34b011..82bcba91f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp @@ -234,9 +234,7 @@ protected: /// same as on_mouse bool use_grabbers(const wxMouseEvent &mouse_event); -#if ENABLE_WORLD_COORDINATE void do_stop_dragging(bool perform_mouse_cleanup); -#endif // ENABLE_WORLD_COORDINATE private: // Flag for dirty visible state of Gizmo diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index b84b70be0..ac74b43b5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -22,6 +22,7 @@ #include "libslic3r/NSVGUtils.hpp" #include "libslic3r/Model.hpp" +#include "libslic3r/Preset.hpp" #include "libslic3r/ClipperUtils.hpp" // union_ex #include "libslic3r/AppConfig.hpp" // store/load font list #include "libslic3r/Format/OBJ.hpp" // load obj file for default object @@ -1425,7 +1426,7 @@ void GLGizmoEmboss::draw_text_input() // show warning about incorrectness view of font std::string warning_tool_tip; if (!exist_font) { - warning_tool_tip = _u8L("Can't write text by selected font.Try to choose another font."); + warning_tool_tip = _u8L("The text cannot be written using the selected font. Please try choosing a different font."); } else { auto append_warning = [&warning_tool_tip](std::string t) { if (!warning_tool_tip.empty()) @@ -1434,15 +1435,15 @@ void GLGizmoEmboss::draw_text_input() }; if (priv::is_text_empty(m_text)) - append_warning(_u8L("Embossed text can NOT contain only white spaces.")); + append_warning(_u8L("Embossed text cannot contain only white spaces.")); if (m_text_contain_unknown_glyph) - append_warning(_u8L("Text contain character glyph (represented by '?') unknown by font.")); + append_warning(_u8L("Text contains character glyph (represented by '?') unknown by font.")); const FontProp &prop = m_style_manager.get_font_prop(); - if (prop.skew.has_value()) append_warning(_u8L("Text input do not show font skew.")); - if (prop.boldness.has_value()) append_warning(_u8L("Text input do not show font boldness.")); + if (prop.skew.has_value()) append_warning(_u8L("Text input doesn't show font skew.")); + if (prop.boldness.has_value()) append_warning(_u8L("Text input doesn't show font boldness.")); if (prop.line_gap.has_value()) - append_warning(_u8L("Text input do not show gap between lines.")); + append_warning(_u8L("Text input doesn't show gap between lines.")); auto &ff = m_style_manager.get_font_file_with_cache(); float imgui_size = StyleManager::get_imgui_font_size(prop, *ff.font_file, scale); if (imgui_size > StyleManager::max_imgui_font_size) @@ -2058,7 +2059,7 @@ void GLGizmoEmboss::draw_font_list() void GLGizmoEmboss::draw_model_type() { bool is_last_solid_part = m_volume->is_the_only_one_part(); - std::string title = _u8L("Text is to object"); + std::string title = _u8L("Operation"); if (is_last_solid_part) { ImVec4 color{.5f, .5f, .5f, 1.f}; m_imgui->text_colored(color, title.c_str()); @@ -2072,14 +2073,15 @@ void GLGizmoEmboss::draw_model_type() ModelVolumeType part = ModelVolumeType::MODEL_PART; ModelVolumeType type = m_volume->type(); - if (ImGui::RadioButton(_u8L("Added").c_str(), type == part)) + //TRN EmbossOperation + if (ImGui::RadioButton(_u8L("Join").c_str(), type == part)) new_type = part; else if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Click to change text into object part.").c_str()); ImGui::SameLine(); std::string last_solid_part_hint = _u8L("You can't change a type of the last solid part of the object."); - if (ImGui::RadioButton(_u8L("Subtracted").c_str(), type == negative)) + if (ImGui::RadioButton(_CTX_utf8(L_CONTEXT("Cut", "EmbossOperation"), "EmbossOperation").c_str(), type == negative)) new_type = negative; else if (ImGui::IsItemHovered()) { if (is_last_solid_part) @@ -2286,7 +2288,7 @@ void GLGizmoEmboss::draw_style_add_button() }else if (only_add_style) { ImGui::SetTooltip("%s", _u8L("Add style to my list.").c_str()); } else { - ImGui::SetTooltip("%s", _u8L("Add as new named style.").c_str()); + ImGui::SetTooltip("%s", _u8L("Save as new style.").c_str()); } } @@ -2302,32 +2304,47 @@ void GLGizmoEmboss::draw_delete_style_button() { bool is_last = m_style_manager.get_styles().size() == 1; bool can_delete = is_stored && !is_last; - std::string title = _u8L("Remove style"); - const char * popup_id = title.c_str(); - static size_t next_style_index = std::numeric_limits::max(); if (draw_button(m_icons, IconType::erase, !can_delete)) { + std::string style_name = m_style_manager.get_style().name; // copy + wxString dialog_title = _L("Remove style"); + size_t next_style_index = std::numeric_limits::max(); + Plater *plater = wxGetApp().plater(); + bool exist_change = false; while (true) { // NOTE: can't use previous loaded activ index -> erase could change index size_t active_index = m_style_manager.get_style_index(); next_style_index = (active_index > 0) ? active_index - 1 : active_index + 1; + if (next_style_index >= m_style_manager.get_styles().size()) { - // can't remove last font style - // TODO: inform user + MessageDialog msg(plater, _L("Can't remove the last exising style."), dialog_title, wxICON_ERROR | wxOK); + msg.ShowModal(); break; } + // IMPROVE: add function can_load? // clean unactivable styles if (!m_style_manager.load_style(next_style_index)) { m_style_manager.erase(next_style_index); + exist_change = true; continue; } - // load back - m_style_manager.load_style(active_index); - ImGui::OpenPopup(popup_id); + wxString message = GUI::format_wxstr(_L("Are you sure,\nthat you want permanently and unrecoverable \nremove \"%1%\" style?"), style_name); + MessageDialog msg(plater, message, dialog_title, wxICON_WARNING | wxYES | wxNO); + if (msg.ShowModal() == wxID_YES) { + // delete style + m_style_manager.erase(active_index); + exist_change = true; + process(); + } else { + // load back style + m_style_manager.load_style(active_index); + } break; } + if (exist_change) + m_style_manager.store_styles_to_app_config(wxGetApp().app_config); } if (ImGui::IsItemHovered()) { @@ -2338,25 +2355,6 @@ void GLGizmoEmboss::draw_delete_style_button() { else/*if(!is_stored)*/ tooltip = GUI::format(_L("Can't delete temporary style \"%1%\"."), style_name); ImGui::SetTooltip("%s", tooltip.c_str()); } - - if (ImGui::BeginPopupModal(popup_id)) { - m_imgui->disable_background_fadeout_animation(); - const std::string &style_name = m_style_manager.get_style().name; - std::string text_in_popup = GUI::format(_L("Are you sure,\nthat you want permanently and unrecoverable \nremove style \"%1%\"?"), style_name); - ImGui::Text("%s", text_in_popup.c_str()); - if (ImGui::Button(_u8L("Yes").c_str())) { - size_t active_index = m_style_manager.get_style_index(); - m_style_manager.load_style(next_style_index); - m_style_manager.erase(active_index); - m_style_manager.store_styles_to_app_config(wxGetApp().app_config); - ImGui::CloseCurrentPopup(); - process(); - } - ImGui::SameLine(); - if (ImGui::Button(_u8L("No").c_str())) - ImGui::CloseCurrentPopup(); - ImGui::EndPopup(); - } } // FIX IT: it should not change volume position before successfull change @@ -2403,7 +2401,7 @@ void GLGizmoEmboss::draw_style_list() { trunc_name = ImGuiWrapper::trunc(current_name, max_style_name_width); } - std::string title = _u8L("Presets"); + std::string title = _u8L("Styles"); if (m_style_manager.exist_stored_style()) ImGui::Text("%s", title.c_str()); else @@ -2412,7 +2410,7 @@ void GLGizmoEmboss::draw_style_list() { ImGui::SetNextItemWidth(m_gui_cfg->input_width); auto add_text_modify = [&is_modified](const std::string& name) { if (!is_modified) return name; - return name + " (" + _u8L("modified") + ")"; + return name + Preset::suffix_modified(); }; std::optional selected_style_index; if (ImGui::BeginCombo("##style_selector", add_text_modify(trunc_name).c_str())) { @@ -2945,17 +2943,17 @@ void GLGizmoEmboss::draw_advanced() } m_imgui->disabled_end(); // !can_use_surface // TRN EmbossGizmo: font units - std::string units = _u8L("font points"); + std::string units = _u8L("points"); std::string units_fmt = "%.0f " + units; - // input gap between letters + // input gap between characters auto def_char_gap = stored_style ? &stored_style->prop.char_gap : nullptr; int half_ascent = font_info.ascent / 2; int min_char_gap = -half_ascent, max_char_gap = half_ascent; - if (rev_slider(tr.char_gap, font_prop.char_gap, def_char_gap, _u8L("Revert gap between letters"), - min_char_gap, max_char_gap, units_fmt, _L("Distance between letters"))){ + if (rev_slider(tr.char_gap, font_prop.char_gap, def_char_gap, _u8L("Revert gap between characters"), + min_char_gap, max_char_gap, units_fmt, _L("Distance between characters"))){ // Condition prevent recalculation when insertint out of limits value by imgui input if (!priv::Limits::apply(font_prop.char_gap, priv::limits.char_gap) || !m_volume->text_configuration->style.prop.char_gap.has_value() || @@ -3017,7 +3015,7 @@ void GLGizmoEmboss::draw_advanced() m_imgui->disabled_begin(!allowe_surface_distance); const std::string undo_move_tooltip = _u8L("Undo translation"); - const wxString move_tooltip = _L("Distance of the center of text from model surface"); + const wxString move_tooltip = _L("Distance of the center of the text to the model surface."); bool is_moved = false; bool use_inch = wxGetApp().app_config->get_bool("use_inches"); if (use_inch) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index d5520403c..92b46aaa2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -358,11 +358,7 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) ++mesh_id; -#if ENABLE_WORLD_COORDINATE const Transform3d trafo_matrix = mi->get_matrix_no_offset() * mv->get_matrix_no_offset(); -#else - const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast().normalized(); Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast().normalized(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp index 6cbec0891..fea8ddc06 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -178,11 +178,7 @@ void GLGizmoFlatten::update_planes() ch = ch.convex_hull_3d(); m_planes.clear(); on_unregister_raycasters_for_picking(); -#if ENABLE_WORLD_COORDINATE const Transform3d inst_matrix = mo->instances.front()->get_matrix_no_offset(); -#else - const Transform3d& inst_matrix = mo->instances.front()->get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE // Following constants are used for discarding too small polygons. const float minimal_area = 5.f; // in square mm (world coordinates) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp index 89e0809fd..374f19edd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp @@ -137,11 +137,7 @@ void GLGizmoHollow::render_points(const Selection& selection) trafo.translation()(2) += shift_z; const Geometry::Transformation transformation{trafo}; -#if ENABLE_WORLD_COORDINATE const Transform3d instance_scaling_matrix_inverse = transformation.get_scaling_factor_matrix().inverse(); -#else - const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse(); -#endif // ENABLE_WORLD_COORDINATE const Camera& camera = wxGetApp().plater()->get_camera(); const Transform3d& view_matrix = camera.get_view_matrix(); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp index 73615b463..3d697c63c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp @@ -1,9 +1,7 @@ #include "GLGizmoMove.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" -#if ENABLE_WORLD_COORDINATE #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "slic3r/GUI/Plater.hpp" #include "libslic3r/Model.hpp" @@ -22,8 +20,7 @@ GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filenam std::string GLGizmoMove3D::get_tooltip() const { -#if ENABLE_WORLD_COORDINATE - if (m_hover_id == 0) + if (m_hover_id == 0) return "X: " + format(m_displacement.x(), 2); else if (m_hover_id == 1) return "Y: " + format(m_displacement.y(), 2); @@ -31,20 +28,6 @@ std::string GLGizmoMove3D::get_tooltip() const return "Z: " + format(m_displacement.z(), 2); else return ""; -#else - const Selection& selection = m_parent.get_selection(); - const bool show_position = selection.is_single_full_instance(); - const Vec3d& position = selection.get_bounding_box().center(); - - if (m_hover_id == 0 || m_grabbers[0].dragging) - return "X: " + format(show_position ? position.x() : m_displacement.x(), 2); - else if (m_hover_id == 1 || m_grabbers[1].dragging) - return "Y: " + format(show_position ? position.y() : m_displacement.y(), 2); - else if (m_hover_id == 2 || m_grabbers[2].dragging) - return "Z: " + format(show_position ? position.z() : m_displacement.z(), 2); - else - return ""; -#endif // ENABLE_WORLD_COORDINATE } bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) { @@ -86,7 +69,6 @@ void GLGizmoMove3D::on_start_dragging() assert(m_hover_id != -1); m_displacement = Vec3d::Zero(); -#if ENABLE_WORLD_COORDINATE const Selection& selection = m_parent.get_selection(); const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); if (coordinates_type == ECoordinatesType::World) @@ -102,13 +84,6 @@ void GLGizmoMove3D::on_start_dragging() m_starting_box_center = m_center; m_starting_box_bottom_center = m_center; m_starting_box_bottom_center.z() = m_bounding_box.min.z(); -#else - const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); - m_starting_drag_position = m_grabbers[m_hover_id].center; - m_starting_box_center = box.center(); - m_starting_box_bottom_center = box.center(); - m_starting_box_bottom_center.z() = box.min.z(); -#endif // ENABLE_WORLD_COORDINATE } void GLGizmoMove3D::on_stop_dragging() @@ -127,7 +102,6 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data) m_displacement.z() = calc_projection(data); Selection &selection = m_parent.get_selection(); -#if ENABLE_WORLD_COORDINATE TransformationType trafo_type; trafo_type.set_relative(); switch (wxGetApp().obj_manipul()->get_coordinates_type()) @@ -137,9 +111,6 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data) default: { break; } } selection.translate(m_displacement, trafo_type); -#else - selection.translate(m_displacement); -#endif // ENABLE_WORLD_COORDINATE } void GLGizmoMove3D::on_render() @@ -147,7 +118,6 @@ void GLGizmoMove3D::on_render() glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); -#if ENABLE_WORLD_COORDINATE const Selection& selection = m_parent.get_selection(); const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system(); m_bounding_box = box; @@ -171,42 +141,16 @@ void GLGizmoMove3D::on_render() // z axis m_grabbers[2].center = { 0.0, 0.0, half_box_size.z() + Offset }; m_grabbers[2].color = AXES_COLOR[2]; -#else - const Selection& selection = m_parent.get_selection(); - const BoundingBoxf3& box = selection.get_bounding_box(); - const Vec3d& center = box.center(); - - // x axis - 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 = { center.x(), box.max.y() + Offset, center.z() }; - m_grabbers[1].color = AXES_COLOR[1]; - - // z axis - m_grabbers[2].center = { center.x(), center.y(), box.max.z() + Offset }; - m_grabbers[2].color = AXES_COLOR[2]; -#endif // ENABLE_WORLD_COORDINATE #if ENABLE_GL_CORE_PROFILE if (!OpenGLManager::get_gl_info().is_core_profile()) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); -#if ENABLE_WORLD_COORDINATE auto render_grabber_connection = [this, &zero](unsigned int id) { -#else - auto render_grabber_connection = [this, ¢er](unsigned int id) { -#endif // ENABLE_WORLD_COORDINATE if (m_grabbers[id].enabled) { -#if ENABLE_WORLD_COORDINATE if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(m_grabbers[id].center)) { m_grabber_connections[id].old_center = m_grabbers[id].center; -#else - if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) { - m_grabber_connections[id].old_center = center; -#endif // ENABLE_WORLD_COORDINATE m_grabber_connections[id].model.reset(); GLModel::Geometry init_data; @@ -216,11 +160,7 @@ void GLGizmoMove3D::on_render() init_data.indices.reserve(2); // vertices -#if ENABLE_WORLD_COORDINATE init_data.add_vertex((Vec3f)zero.cast()); -#else - init_data.add_vertex((Vec3f)center.cast()); -#endif // ENABLE_WORLD_COORDINATE init_data.add_vertex((Vec3f)m_grabbers[id].center.cast()); // indices @@ -242,11 +182,7 @@ void GLGizmoMove3D::on_render() if (shader != nullptr) { shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_WORLD_COORDINATE shader->set_uniform("view_model_matrix", camera.get_view_matrix() * base_matrix); -#else - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); -#endif // ENABLE_WORLD_COORDINATE shader->set_uniform("projection_matrix", camera.get_projection_matrix()); #if ENABLE_GL_CORE_PROFILE const std::array& viewport = camera.get_viewport(); @@ -264,11 +200,7 @@ void GLGizmoMove3D::on_render() } // draw grabbers -#if ENABLE_WORLD_COORDINATE render_grabbers(m_bounding_box); -#else - render_grabbers(box); -#endif // ENABLE_WORLD_COORDINATE } else { // draw axis @@ -281,11 +213,7 @@ void GLGizmoMove3D::on_render() shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_WORLD_COORDINATE shader->set_uniform("view_model_matrix", camera.get_view_matrix()* base_matrix); -#else - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); -#endif // ENABLE_WORLD_COORDINATE shader->set_uniform("projection_matrix", camera.get_projection_matrix()); #if ENABLE_GL_CORE_PROFILE const std::array& viewport = camera.get_viewport(); @@ -303,11 +231,7 @@ void GLGizmoMove3D::on_render() shader->start_using(); shader->set_uniform("emission_factor", 0.1f); // draw grabber -#if ENABLE_WORLD_COORDINATE const Vec3d box_size = m_bounding_box.size(); -#else - const Vec3d box_size = box.size(); -#endif // ENABLE_WORLD_COORDINATE const 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(); @@ -352,7 +276,6 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const return projection; } -#if ENABLE_WORLD_COORDINATE Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const { Transform3d ret = Geometry::translation_transform(m_center); @@ -365,7 +288,6 @@ Transform3d GLGizmoMove3D::local_transform(const Selection& selection) const } return ret; } -#endif // ENABLE_WORLD_COORDINATE } // namespace GUI } // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp index cd92d7472..371cda80a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp @@ -7,19 +7,15 @@ namespace Slic3r { namespace GUI { -#if ENABLE_WORLD_COORDINATE class Selection; -#endif // ENABLE_WORLD_COORDINATE class GLGizmoMove3D : public GLGizmoBase { static const double Offset; Vec3d m_displacement{ Vec3d::Zero() }; -#if ENABLE_WORLD_COORDINATE Vec3d m_center{ Vec3d::Zero() }; BoundingBoxf3 m_bounding_box; -#endif // ENABLE_WORLD_COORDINATE double m_snap_step{ 1.0 }; Vec3d m_starting_drag_position{ Vec3d::Zero() }; Vec3d m_starting_box_center{ Vec3d::Zero() }; @@ -65,9 +61,7 @@ protected: private: double calc_projection(const UpdateData& data) const; -#if ENABLE_WORLD_COORDINATE Transform3d local_transform(const Selection& selection) const; -#endif // ENABLE_WORLD_COORDINATE }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index aa3d56ef9..0a2f9f098 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -266,11 +266,7 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const if (shader == nullptr) return; -#if ENABLE_WORLD_COORDINATE const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_scaling_factor_matrix().inverse(); -#else - const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse(); -#endif // ENABLE_WORLD_COORDINATE ColorRGBA render_color = { 0.0f, 0.0f, 0.0f, 0.25f }; if (m_button_down == Button::Left) @@ -465,11 +461,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const Selection &selection = m_parent.get_selection(); const ModelObject *mo = m_c->selection_info()->model_object(); const ModelInstance *mi = mo->instances[selection.get_instance_idx()]; -#if ENABLE_WORLD_COORDINATE const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix_no_offset() * mo->volumes[m_rr.mesh_id]->get_matrix_no_offset(); -#else - const Transform3d trafo_matrix_not_translate = mi->get_transformation().get_matrix(true) * mo->volumes[m_rr.mesh_id]->get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE const Transform3d trafo_matrix = mi->get_transformation().get_matrix() * mo->volumes[m_rr.mesh_id]->get_matrix(); m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), trafo_matrix_not_translate, this->get_clipping_plane_in_volume_coordinates(trafo_matrix), m_smart_fill_angle, m_paint_on_overhangs_only ? m_highlight_by_angle_threshold_deg : 0.f, true); @@ -508,11 +500,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const ModelObject *mo = m_c->selection_info()->model_object(); const ModelInstance *mi = mo->instances[selection.get_instance_idx()]; const Transform3d instance_trafo = mi->get_transformation().get_matrix(); -#if ENABLE_WORLD_COORDINATE const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix_no_offset(); -#else - const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE // Precalculate transformations of individual meshes. std::vector trafo_matrices; @@ -520,11 +508,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous for (const ModelVolume *mv : mo->volumes) if (mv->is_model_part()) { trafo_matrices.emplace_back(instance_trafo * mv->get_matrix()); -#if ENABLE_WORLD_COORDINATE trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix_no_offset()); -#else - trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true)); -#endif // ENABLE_WORLD_COORDINATE } std::vector> projected_mouse_positions_by_mesh = get_projected_mouse_positions(mouse_position, 1., trafo_matrices); @@ -606,11 +590,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous const ModelObject *mo = m_c->selection_info()->model_object(); const ModelInstance *mi = mo->instances[selection.get_instance_idx()]; const Transform3d instance_trafo = mi->get_transformation().get_matrix(); -#if ENABLE_WORLD_COORDINATE const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix_no_offset(); -#else - const Transform3d instance_trafo_not_translate = mi->get_transformation().get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE // Precalculate transformations of individual meshes. std::vector trafo_matrices; @@ -618,11 +598,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous for (const ModelVolume *mv : mo->volumes) if (mv->is_model_part()) { trafo_matrices.emplace_back(instance_trafo * mv->get_matrix()); -#if ENABLE_WORLD_COORDINATE trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate* mv->get_matrix_no_offset()); -#else - trafo_matrices_not_translate.emplace_back(instance_trafo_not_translate * mv->get_matrix(true)); -#endif // ENABLE_WORLD_COORDINATE } // Now "click" into all the prepared points and spill paint around them. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 75b80d8f5..2636486a7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -1,9 +1,7 @@ #include "GLGizmoRotate.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/ImGuiWrapper.hpp" -#if ENABLE_WORLD_COORDINATE #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI.hpp" @@ -100,27 +98,12 @@ bool GLGizmoRotate::on_init() void GLGizmoRotate::on_start_dragging() { -#if ENABLE_WORLD_COORDINATE init_data_from_selection(m_parent.get_selection()); -#else - const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box(); - m_center = box.center(); - m_radius = Offset + box.radius(); - m_snap_coarse_in_radius = m_radius / 3.0f; - m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius; - m_snap_fine_in_radius = m_radius; - m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth; -#endif // ENABLE_WORLD_COORDINATE } void GLGizmoRotate::on_dragging(const UpdateData &data) { -#if ENABLE_WORLD_COORDINATE const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray)); -#else - const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection())); -#endif // ENABLE_WORLD_COORDINATE - const Vec2d orig_dir = Vec2d::UnitX(); const Vec2d new_dir = mouse_pos.normalized(); @@ -155,22 +138,8 @@ void GLGizmoRotate::on_render() return; const Selection& selection = m_parent.get_selection(); -#if !ENABLE_WORLD_COORDINATE - const BoundingBoxf3& box = selection.get_bounding_box(); -#endif // !ENABLE_WORLD_COORDINATE - - if (m_hover_id != 0 && !m_grabbers.front().dragging) { -#if ENABLE_WORLD_COORDINATE + if (m_hover_id != 0 && !m_grabbers.front().dragging) init_data_from_selection(selection); -#else - m_center = box.center(); - m_radius = Offset + box.radius(); - m_snap_coarse_in_radius = m_radius / 3.0f; - m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius; - m_snap_fine_in_radius = m_radius; - m_snap_fine_out_radius = m_radius * (1.0f + ScaleLongTooth); -#endif // ENABLE_WORLD_COORDINATE - } const double grabber_radius = (double)m_radius * (1.0 + (double)GrabberOffset); m_grabbers.front().center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0); @@ -223,14 +192,9 @@ void GLGizmoRotate::on_render() shader->stop_using(); } -#if ENABLE_WORLD_COORDINATE render_grabber(m_bounding_box); -#else - render_grabber(box); -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE void GLGizmoRotate::init_data_from_selection(const Selection& selection) { const auto [box, box_trafo] = m_force_local_coordinate ? @@ -245,7 +209,6 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection) m_snap_fine_in_radius = m_radius; m_snap_fine_out_radius = m_snap_fine_in_radius + m_radius * ScaleLongTooth; } -#endif // ENABLE_WORLD_COORDINATE void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit) { @@ -472,20 +435,12 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const { case X: { -#if ENABLE_WORLD_COORDINATE ret = Geometry::rotation_transform(0.5 * PI * Vec3d::UnitY()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()); -#else - ret = Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()); -#endif // ENABLE_WORLD_COORDINATE break; } case Y: { -#if ENABLE_WORLD_COORDINATE ret = Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitZ()) * Geometry::rotation_transform(-0.5 * PI * Vec3d::UnitY()); -#else - ret = Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitZ()) * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitY()); -#endif // ENABLE_WORLD_COORDINATE break; } default: @@ -496,21 +451,10 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const } } -#if ENABLE_WORLD_COORDINATE return m_orient_matrix * ret; -#else - if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) - ret = selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true) * ret; - - return Geometry::assemble_transform(m_center) * ret; -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) const -#else -Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const -#endif // ENABLE_WORLD_COORDINATE { const double half_pi = 0.5 * double(PI); @@ -538,12 +482,7 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, cons } } -#if ENABLE_WORLD_COORDINATE m = m * Geometry::Transformation(m_orient_matrix).get_matrix_no_offset().inverse(); -#else - if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes()) - m = m * selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true).inverse(); -#endif // ENABLE_WORLD_COORDINATE m.translate(-m_center); @@ -577,7 +516,6 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) { if (mouse_event.Dragging() && m_dragging) { // Apply new temporary rotations -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (m_parent.get_selection().is_wipe_tower()) transformation_type = TransformationType::World_Relative_Joint; @@ -590,9 +528,6 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) case ECoordinatesType::Local: { transformation_type = TransformationType::Local_Relative_Joint; break; } } } -#else - TransformationType transformation_type(TransformationType::World_Relative_Joint); -#endif // ENABLE_WORLD_COORDINATE if (mouse_event.AltDown()) transformation_type.set_independent(); m_parent.get_selection().rotate(get_rotation(), transformation_type); @@ -602,26 +537,14 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) void GLGizmoRotate3D::data_changed() { if (m_parent.get_selection().is_wipe_tower()) { -#if !ENABLE_WORLD_COORDINATE - const DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config; - const float wipe_tower_rotation_angle = - dynamic_cast( - config.option("wipe_tower_rotation_angle"))->value; - set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle)); -#endif // !ENABLE_WORLD_COORDINATE m_gizmos[0].disable_grabber(); m_gizmos[1].disable_grabber(); } else { -#if !ENABLE_WORLD_COORDINATE - set_rotation(Vec3d::Zero()); -#endif // !ENABLE_WORLD_COORDINATE m_gizmos[0].enable_grabber(); m_gizmos[1].enable_grabber(); } -#if ENABLE_WORLD_COORDINATE set_rotation(Vec3d::Zero()); -#endif // ENABLE_WORLD_COORDINATE } bool GLGizmoRotate3D::on_init() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index ebfed1920..a1bb2ee44 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -35,10 +35,8 @@ private: float m_snap_coarse_out_radius{ 0.0f }; float m_snap_fine_in_radius{ 0.0f }; float m_snap_fine_out_radius{ 0.0f }; -#if ENABLE_WORLD_COORDINATE BoundingBoxf3 m_bounding_box; Transform3d m_orient_matrix{ Transform3d::Identity() }; -#endif // ENABLE_WORLD_COORDINATE GLModel m_circle; GLModel m_scale; @@ -109,15 +107,9 @@ private: Transform3d local_transform(const Selection& selection) const; // returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate -#if ENABLE_WORLD_COORDINATE Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray) const; -#else - Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const; -#endif // ENABLE_WORLD_COORDINATE -#if ENABLE_WORLD_COORDINATE void init_data_from_selection(const Selection& selection); -#endif // ENABLE_WORLD_COORDINATE }; class GLGizmoRotate3D : public GLGizmoBase diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 063dce721..5e6ab1ae6 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -1,9 +1,7 @@ #include "GLGizmoScale.hpp" #include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GUI_App.hpp" -#if ENABLE_WORLD_COORDINATE #include "slic3r/GUI/GUI_ObjectManipulation.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "slic3r/GUI/Plater.hpp" #include "libslic3r/Model.hpp" @@ -20,7 +18,6 @@ const double GLGizmoScale3D::Offset = 5.0; GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id) , m_scale(Vec3d::Ones()) - , m_offset(Vec3d::Zero()) , m_snap_step(0.05) , m_base_color(DEFAULT_BASE_COLOR) , m_drag_color(DEFAULT_DRAG_COLOR) @@ -37,17 +34,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen std::string GLGizmoScale3D::get_tooltip() const { -#if ENABLE_WORLD_COORDINATE const Vec3d scale = 100.0 * m_scale; -#else - const Selection& selection = m_parent.get_selection(); - - Vec3d scale = 100.0 * Vec3d::Ones(); - if (selection.is_single_full_instance()) - scale = 100.0 * selection.get_first_volume()->get_instance_scaling_factor(); - else if (selection.is_single_modifier() || selection.is_single_volume()) - scale = 100.0 * selection.get_first_volume()->get_volume_scaling_factor(); -#endif // ENABLE_WORLD_COORDINATE if (m_hover_id == 0 || m_hover_id == 1 || m_grabbers[0].dragging || m_grabbers[1].dragging) return "X: " + format(scale.x(), 4) + "%"; @@ -67,12 +54,17 @@ std::string GLGizmoScale3D::get_tooltip() const return ""; } +static int constraint_id(int grabber_id) +{ + static const std::vector id_map = { 1, 0, 3, 2, 5, 4, 8, 9, 6, 7 }; + return (0 <= grabber_id && grabber_id < (int)id_map.size()) ? id_map[grabber_id] : -1; +} + bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event) { if (mouse_event.Dragging()) { if (m_dragging) { // Apply new temporary scale factors -#if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (wxGetApp().obj_manipul()->is_local_coordinates()) transformation_type.set_local(); @@ -80,20 +72,22 @@ bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event) transformation_type.set_instance(); transformation_type.set_relative(); -#else - TransformationType transformation_type(TransformationType::Local_Absolute_Joint); -#endif // ENABLE_WORLD_COORDINATE if (mouse_event.AltDown()) transformation_type.set_independent(); -#if ENABLE_WORLD_COORDINATE - m_parent.get_selection().scale_and_translate(m_scale, m_offset, transformation_type); -#else Selection& selection = m_parent.get_selection(); selection.scale(m_scale, transformation_type); - if (mouse_event.CmdDown()) selection.translate(m_offset, true); -#endif // ENABLE_WORLD_COORDINATE + if (m_starting.ctrl_down) { + // constrained scale: + // uses the performed scale to calculate the new position of the constrained grabber + // and from that calculates the offset (in world coordinates) to be applied to fullfill the constraint + update_render_data(); + const Vec3d constraint_position = m_grabbers_transform * m_grabbers[constraint_id(m_hover_id)].center; + // re-apply the scale because the selection always applies the transformations with respect to the initial state + // set into on_start_dragging() with the call to selection.setup_cache() + m_parent.get_selection().scale_and_translate(m_scale, m_starting.constraint_position - constraint_position, transformation_type); + } } } return use_grabbers(mouse_event); @@ -107,29 +101,7 @@ void GLGizmoScale3D::enable_ununiversal_scale(bool enable) void GLGizmoScale3D::data_changed() { -#if ENABLE_WORLD_COORDINATE set_scale(Vec3d::Ones()); -#else - const Selection& selection = m_parent.get_selection(); - bool enable_scale_xyz = selection.is_single_full_instance() || - selection.is_single_volume() || - selection.is_single_modifier(); - - for (unsigned int i = 0; i < 6; ++i) - m_grabbers[i].enabled = enable_scale_xyz; - - if (enable_scale_xyz) { - // all volumes in the selection belongs to the same instance, any of - // them contains the needed data, so we take the first - const GLVolume* volume = selection.get_first_volume(); - if (selection.is_single_full_instance()) - set_scale(volume->get_instance_scaling_factor()); - else if (selection.is_single_volume() || selection.is_single_modifier()) - set_scale(volume->get_volume_scaling_factor()); - } - else - set_scale(Vec3d::Ones()); -#endif // ENABLE_WORLD_COORDINATE } bool GLGizmoScale3D::on_init() @@ -138,20 +110,7 @@ bool GLGizmoScale3D::on_init() m_grabbers.push_back(Grabber()); } -#if !ENABLE_WORLD_COORDINATE - double half_pi = 0.5 * (double)PI; - - // x axis - m_grabbers[0].angles.y() = half_pi; - m_grabbers[1].angles.y() = half_pi; - - // y axis - m_grabbers[2].angles.x() = half_pi; - m_grabbers[3].angles.x() = half_pi; -#endif // !ENABLE_WORLD_COORDINATE - m_shortcut_key = WXK_CONTROL_S; - return true; } @@ -170,27 +129,17 @@ void GLGizmoScale3D::on_start_dragging() { assert(m_hover_id != -1); m_starting.ctrl_down = wxGetKeyState(WXK_CONTROL); -#if ENABLE_WORLD_COORDINATE m_starting.drag_position = m_grabbers_transform * m_grabbers[m_hover_id].center; m_starting.box = m_bounding_box; m_starting.center = m_center; m_starting.instance_center = m_instance_center; -#else - m_starting.drag_position = m_grabbers[m_hover_id].center; - m_starting.box = (m_starting.ctrl_down && m_hover_id < 6) ? m_bounding_box : m_parent.get_selection().get_bounding_box(); - - const Vec3d& center = m_starting.box.center(); - m_starting.pivots[0] = m_transform * Vec3d(m_starting.box.max.x(), center.y(), center.z()); - m_starting.pivots[1] = m_transform * Vec3d(m_starting.box.min.x(), center.y(), center.z()); - m_starting.pivots[2] = m_transform * Vec3d(center.x(), m_starting.box.max.y(), center.z()); - m_starting.pivots[3] = m_transform * Vec3d(center.x(), m_starting.box.min.y(), center.z()); - m_starting.pivots[4] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.max.z()); - m_starting.pivots[5] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.min.z()); -#endif // ENABLE_WORLD_COORDINATE + m_starting.constraint_position = m_grabbers_transform * m_grabbers[constraint_id(m_hover_id)].center; } -void GLGizmoScale3D::on_stop_dragging() { +void GLGizmoScale3D::on_stop_dragging() +{ m_parent.do_scale(L("Gizmo-Scale")); + m_starting.ctrl_down = false; } void GLGizmoScale3D::on_dragging(const UpdateData& data) @@ -205,60 +154,18 @@ void GLGizmoScale3D::on_dragging(const UpdateData& data) do_scale_uniform(data); } -#if ENABLE_WORLD_COORDINATE void GLGizmoScale3D::on_render() { - const Selection& selection = m_parent.get_selection(); - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); - const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system(); - m_bounding_box = box; - m_center = box_trafo.translation(); - m_grabbers_transform = box_trafo; - m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center; - - // x axis - const Vec3d box_half_size = 0.5 * m_bounding_box.size(); - bool use_constrain = wxGetKeyState(WXK_CONTROL) && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()); - - m_grabbers[0].center = { -(box_half_size.x() + Offset), 0.0, 0.0 }; - m_grabbers[0].color = (use_constrain && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0]; - m_grabbers[1].center = { box_half_size.x() + Offset, 0.0, 0.0 }; - m_grabbers[1].color = (use_constrain && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0]; - - // y axis - m_grabbers[2].center = { 0.0, -(box_half_size.y() + Offset), 0.0 }; - m_grabbers[2].color = (use_constrain && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1]; - m_grabbers[3].center = { 0.0, box_half_size.y() + Offset, 0.0 }; - m_grabbers[3].color = (use_constrain && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1]; - - // z axis - m_grabbers[4].center = { 0.0, 0.0, -(box_half_size.z() + Offset) }; - m_grabbers[4].color = (use_constrain && m_hover_id == 5) ? CONSTRAINED_COLOR : AXES_COLOR[2]; - m_grabbers[5].center = { 0.0, 0.0, box_half_size.z() + Offset }; - m_grabbers[5].color = (use_constrain && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2]; - - // uniform - m_grabbers[6].center = { -(box_half_size.x() + Offset), -(box_half_size.y() + Offset), 0.0 }; - m_grabbers[6].color = (use_constrain && m_hover_id == 8) ? CONSTRAINED_COLOR : m_highlight_color; - m_grabbers[7].center = { box_half_size.x() + Offset, -(box_half_size.y() + Offset), 0.0 }; - m_grabbers[7].color = (use_constrain && m_hover_id == 9) ? CONSTRAINED_COLOR : m_highlight_color; - m_grabbers[8].center = { box_half_size.x() + Offset, box_half_size.y() + Offset, 0.0 }; - m_grabbers[8].color = (use_constrain && m_hover_id == 6) ? CONSTRAINED_COLOR : m_highlight_color; - m_grabbers[9].center = { -(box_half_size.x() + Offset), box_half_size.y() + Offset, 0.0 }; - m_grabbers[9].color = (use_constrain && m_hover_id == 7) ? CONSTRAINED_COLOR : m_highlight_color; + update_render_data(); #if ENABLE_GL_CORE_PROFILE if (!OpenGLManager::get_gl_info().is_core_profile()) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - for (int i = 0; i < 10; ++i) { - m_grabbers[i].matrix = m_grabbers_transform; - } - const float grabber_mean_size = (float)((m_bounding_box.size().x() + m_bounding_box.size().y() + m_bounding_box.size().z()) / 3.0); if (m_hover_id == -1) { @@ -423,267 +330,6 @@ void GLGizmoScale3D::on_render() } } } -#else -void GLGizmoScale3D::on_render() -{ - const Selection& selection = m_parent.get_selection(); - - glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - m_bounding_box.reset(); - m_transform = Transform3d::Identity(); - // Transforms grabbers' offsets to world refefence system - Transform3d offsets_transform = Transform3d::Identity(); - m_offsets_transform = Transform3d::Identity(); - Vec3d angles = Vec3d::Zero(); - - if (selection.is_single_full_instance()) { - // calculate bounding box in instance local reference system - const Selection::IndicesList& idxs = selection.get_volume_idxs(); - for (unsigned int idx : idxs) { - const GLVolume& v = *selection.get_volume(idx); - m_bounding_box.merge(v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_matrix())); - } - - // gets transform from first selected volume - const GLVolume& v = *selection.get_first_volume(); - m_transform = v.get_instance_transformation().get_matrix(); - - // gets angles from first selected volume - angles = v.get_instance_rotation(); - // consider rotation+mirror only components of the transform for offsets - offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v.get_instance_mirror()); - m_offsets_transform = offsets_transform; - } - else if (selection.is_single_modifier() || selection.is_single_volume()) { - const GLVolume& v = *selection.get_first_volume(); - m_bounding_box = v.bounding_box(); - m_transform = v.world_matrix(); - angles = Geometry::extract_rotation(m_transform); - // consider rotation+mirror only components of the transform for offsets - offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), angles, Vec3d::Ones(), v.get_instance_mirror()); - m_offsets_transform = Geometry::assemble_transform(Vec3d::Zero(), v.get_volume_rotation(), Vec3d::Ones(), v.get_volume_mirror()); - } - else - m_bounding_box = selection.get_bounding_box(); - - const Vec3d& center = m_bounding_box.center(); - const Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0); - const Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0); - const Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset); - - const bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL)); - - // x axis - m_grabbers[0].center = m_transform * Vec3d(m_bounding_box.min.x(), center.y(), center.z()) - 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_bounding_box.max.x(), center.y(), center.z()) + offset_x; - 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.x(), m_bounding_box.min.y(), center.z()) - 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.x(), m_bounding_box.max.y(), center.z()) + offset_y; - 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.x(), center.y(), m_bounding_box.min.z()) - 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.x(), center.y(), m_bounding_box.max.z()) + offset_z; - m_grabbers[5].color = (ctrl_down && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2]; - - // uniform - m_grabbers[6].center = m_transform * Vec3d(m_bounding_box.min.x(), m_bounding_box.min.y(), center.z()) - offset_x - offset_y; - m_grabbers[7].center = m_transform * Vec3d(m_bounding_box.max.x(), m_bounding_box.min.y(), center.z()) + offset_x - offset_y; - m_grabbers[8].center = m_transform * Vec3d(m_bounding_box.max.x(), m_bounding_box.max.y(), center.z()) + offset_x + offset_y; - m_grabbers[9].center = m_transform * Vec3d(m_bounding_box.min.x(), m_bounding_box.max.y(), center.z()) - offset_x + offset_y; - - for (int i = 6; i < 10; ++i) { - m_grabbers[i].color = m_highlight_color; - } - - // sets grabbers orientation - for (int i = 0; i < 10; ++i) { - m_grabbers[i].angles = angles; - } - -#if ENABLE_GL_CORE_PROFILE - if (!OpenGLManager::get_gl_info().is_core_profile()) -#endif // ENABLE_GL_CORE_PROFILE - glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f)); - - const BoundingBoxf3& selection_box = selection.get_bounding_box(); - const float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0); - - if (m_hover_id == -1) { - // draw connections -#if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); -#else - GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE - if (shader != nullptr) { - shader->start_using(); - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_GL_CORE_PROFILE - const std::array& viewport = camera.get_viewport(); - shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); - shader->set_uniform("width", 0.25f); - shader->set_uniform("gap_size", 0.0f); -#endif // ENABLE_GL_CORE_PROFILE - if (m_grabbers[0].enabled && m_grabbers[1].enabled) - render_grabbers_connection(0, 1, m_grabbers[0].color); - if (m_grabbers[2].enabled && m_grabbers[3].enabled) - render_grabbers_connection(2, 3, m_grabbers[2].color); - if (m_grabbers[4].enabled && m_grabbers[5].enabled) - render_grabbers_connection(4, 5, m_grabbers[4].color); - render_grabbers_connection(6, 7, m_base_color); - render_grabbers_connection(7, 8, m_base_color); - render_grabbers_connection(8, 9, m_base_color); - render_grabbers_connection(9, 6, m_base_color); - shader->stop_using(); - } - - // draw grabbers - render_grabbers(grabber_mean_size); - } - else if ((m_hover_id == 0 || m_hover_id == 1) && m_grabbers[0].enabled && m_grabbers[1].enabled) { - // draw connections -#if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); -#else - GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE - if (shader != nullptr) { - shader->start_using(); - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_GL_CORE_PROFILE - const std::array& viewport = camera.get_viewport(); - shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); - shader->set_uniform("width", 0.25f); - shader->set_uniform("gap_size", 0.0f); -#endif // ENABLE_GL_CORE_PROFILE - render_grabbers_connection(0, 1, m_grabbers[0].color); - shader->stop_using(); - } - - // draw grabbers - shader = wxGetApp().get_shader("gouraud_light"); - if (shader != nullptr) { - shader->start_using(); - shader->set_uniform("emission_factor", 0.1f); - 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) && m_grabbers[2].enabled && m_grabbers[3].enabled) { - // draw connections -#if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); -#else - GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE - if (shader != nullptr) { - shader->start_using(); - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_GL_CORE_PROFILE - const std::array& viewport = camera.get_viewport(); - shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); - shader->set_uniform("width", 0.25f); - shader->set_uniform("gap_size", 0.0f); -#endif // ENABLE_GL_CORE_PROFILE - render_grabbers_connection(2, 3, m_grabbers[2].color); - shader->stop_using(); - } - - // draw grabbers - shader = wxGetApp().get_shader("gouraud_light"); - if (shader != nullptr) { - shader->start_using(); - shader->set_uniform("emission_factor", 0.1f); - 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) && m_grabbers[4].enabled && m_grabbers[5].enabled) { - // draw connections -#if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); -#else - GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE - if (shader != nullptr) { - shader->start_using(); - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_GL_CORE_PROFILE - const std::array& viewport = camera.get_viewport(); - shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); - shader->set_uniform("width", 0.25f); - shader->set_uniform("gap_size", 0.0f); -#endif // ENABLE_GL_CORE_PROFILE - render_grabbers_connection(4, 5, m_grabbers[4].color); - shader->stop_using(); - } - - // draw grabbers - shader = wxGetApp().get_shader("gouraud_light"); - if (shader != nullptr) { - shader->start_using(); - shader->set_uniform("emission_factor", 0.1f); - 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) { - // draw connections -#if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); -#else - GLShaderProgram* shader = wxGetApp().get_shader("flat"); -#endif // ENABLE_GL_CORE_PROFILE - if (shader != nullptr) { - shader->start_using(); - const Camera& camera = wxGetApp().plater()->get_camera(); - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); - shader->set_uniform("projection_matrix", camera.get_projection_matrix()); -#if ENABLE_GL_CORE_PROFILE - const std::array& viewport = camera.get_viewport(); - shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); - shader->set_uniform("width", 0.25f); - shader->set_uniform("gap_size", 0.0f); -#endif // ENABLE_GL_CORE_PROFILE - render_grabbers_connection(6, 7, m_drag_color); - render_grabbers_connection(7, 8, m_drag_color); - render_grabbers_connection(8, 9, m_drag_color); - render_grabbers_connection(9, 6, m_drag_color); - shader->stop_using(); - } - - // draw grabbers - shader = wxGetApp().get_shader("gouraud_light"); - if (shader != nullptr) { - shader->start_using(); - shader->set_uniform("emission_factor", 0.1f); - for (int i = 6; i < 10; ++i) { - m_grabbers[i].render(true, grabber_mean_size); - } - shader->stop_using(); - } - } -} -#endif // ENABLE_WORLD_COORDINATE void GLGizmoScale3D::on_register_raycasters_for_picking() { @@ -736,127 +382,27 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int m_grabber_connections[id].model.render(); } -#if ENABLE_WORLD_COORDINATE void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data) { double ratio = calc_ratio(data); if (ratio > 0.0) { Vec3d curr_scale = m_scale; - const Vec3d starting_scale = m_starting.scale; - const Selection& selection = m_parent.get_selection(); - const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); - - curr_scale(axis) = starting_scale(axis) * ratio; + curr_scale(axis) = m_starting.scale(axis) * ratio; m_scale = curr_scale; - - if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) { - double local_offset = 0.5 * (ratio - 1.0) * m_starting.box.size()(axis); - - if (m_hover_id == 2 * axis) - local_offset *= -1.0; - - switch (axis) - { - case X: { m_offset = local_offset * Vec3d::UnitX(); break; } - case Y: { m_offset = local_offset * Vec3d::UnitY(); break; } - case Z: { m_offset = local_offset * Vec3d::UnitZ(); break; } - default: { m_offset = Vec3d::Zero(); break; } - } - - if (selection.is_single_volume_or_modifier()) { - if (coordinates_type == ECoordinatesType::Instance) - m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset; - else if (coordinates_type == ECoordinatesType::Local) { - m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * - selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset; - } - } - } - else - m_offset = Vec3d::Zero(); } } -#else -void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data) -{ - const double ratio = calc_ratio(data); - if (ratio > 0.0) { - m_scale(axis) = m_starting.scale(axis) * ratio; - if (m_starting.ctrl_down) { - double local_offset = 0.5 * (m_scale(axis) - m_starting.scale(axis)) * m_starting.box.size()(axis); - - if (m_hover_id == 2 * axis) - local_offset *= -1.0; - - Vec3d local_offset_vec; - switch (axis) - { - case X: { local_offset_vec = local_offset * Vec3d::UnitX(); break; } - case Y: { local_offset_vec = local_offset * Vec3d::UnitY(); break; } - case Z: { local_offset_vec = local_offset * Vec3d::UnitZ(); break; } - default: break; - } - - m_offset = m_offsets_transform * local_offset_vec; - } - else - m_offset = Vec3d::Zero(); - } -} -#endif // ENABLE_WORLD_COORDINATE - -#if ENABLE_WORLD_COORDINATE void GLGizmoScale3D::do_scale_uniform(const UpdateData & data) { const double ratio = calc_ratio(data); - if (ratio > 0.0) { + if (ratio > 0.0) m_scale = m_starting.scale * ratio; - - const Selection& selection = m_parent.get_selection(); - const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); - if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) { - m_offset = 0.5 * (ratio - 1.0) * m_starting.box.size(); - - if (m_hover_id == 6 || m_hover_id == 9) - m_offset.x() *= -1.0; - if (m_hover_id == 6 || m_hover_id == 7) - m_offset.y() *= -1.0; - - if (selection.is_single_volume_or_modifier()) { - if (coordinates_type == ECoordinatesType::Instance) - m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset; - else if (coordinates_type == ECoordinatesType::Local) { - m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * - selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset; - } - } - } - else - m_offset = Vec3d::Zero(); - } } -#else -void GLGizmoScale3D::do_scale_uniform(const UpdateData& data) -{ - const double ratio = calc_ratio(data); - if (ratio > 0.0) { - m_scale = m_starting.scale * ratio; - m_offset = Vec3d::Zero(); - } -} -#endif // ENABLE_WORLD_COORDINATE double GLGizmoScale3D::calc_ratio(const UpdateData& data) const { double ratio = 0.0; - -#if ENABLE_WORLD_COORDINATE const Vec3d starting_vec = m_starting.drag_position - m_starting.center; -#else - const Vec3d pivot = (m_starting.ctrl_down && m_hover_id < 6) ? m_starting.pivots[m_hover_id] : m_starting.box.center(); - const Vec3d starting_vec = m_starting.drag_position - pivot; -#endif // ENABLE_WORLD_COORDINATE const double len_starting_vec = starting_vec.norm(); @@ -882,5 +428,50 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const return ratio; } +void GLGizmoScale3D::update_render_data() +{ + const Selection& selection = m_parent.get_selection(); + const auto& [box, box_trafo] = selection.get_bounding_box_in_current_reference_system(); + m_bounding_box = box; + m_center = box_trafo.translation(); + m_grabbers_transform = box_trafo; + m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center; + + const Vec3d box_half_size = 0.5 * m_bounding_box.size(); + bool use_constrain = wxGetKeyState(WXK_CONTROL); + + // x axis + m_grabbers[0].center = { -(box_half_size.x() + Offset), 0.0, 0.0 }; + m_grabbers[0].color = (use_constrain && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0]; + m_grabbers[1].center = { box_half_size.x() + Offset, 0.0, 0.0 }; + m_grabbers[1].color = (use_constrain && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0]; + + // y axis + m_grabbers[2].center = { 0.0, -(box_half_size.y() + Offset), 0.0 }; + m_grabbers[2].color = (use_constrain && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1]; + m_grabbers[3].center = { 0.0, box_half_size.y() + Offset, 0.0 }; + m_grabbers[3].color = (use_constrain && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1]; + + // z axis + m_grabbers[4].center = { 0.0, 0.0, -(box_half_size.z() + Offset) }; + m_grabbers[4].color = (use_constrain && m_hover_id == 5) ? CONSTRAINED_COLOR : AXES_COLOR[2]; + m_grabbers[5].center = { 0.0, 0.0, box_half_size.z() + Offset }; + m_grabbers[5].color = (use_constrain && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2]; + + // uniform + m_grabbers[6].center = { -(box_half_size.x() + Offset), -(box_half_size.y() + Offset), 0.0 }; + m_grabbers[6].color = (use_constrain && m_hover_id == 8) ? CONSTRAINED_COLOR : m_highlight_color; + m_grabbers[7].center = { box_half_size.x() + Offset, -(box_half_size.y() + Offset), 0.0 }; + m_grabbers[7].color = (use_constrain && m_hover_id == 9) ? CONSTRAINED_COLOR : m_highlight_color; + m_grabbers[8].center = { box_half_size.x() + Offset, box_half_size.y() + Offset, 0.0 }; + m_grabbers[8].color = (use_constrain && m_hover_id == 6) ? CONSTRAINED_COLOR : m_highlight_color; + m_grabbers[9].center = { -(box_half_size.x() + Offset), box_half_size.y() + Offset, 0.0 }; + m_grabbers[9].color = (use_constrain && m_hover_id == 7) ? CONSTRAINED_COLOR : m_highlight_color; + + for (int i = 0; i < 10; ++i) { + m_grabbers[i].matrix = m_grabbers_transform; + } +} + } // namespace GUI } // namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp index fe6ab4972..d0b239c33 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp @@ -3,16 +3,10 @@ #include "GLGizmoBase.hpp" -#if !ENABLE_WORLD_COORDINATE -#include "libslic3r/BoundingBox.hpp" -#endif // !ENABLE_WORLD_COORDINATE - namespace Slic3r { namespace GUI { -#if ENABLE_WORLD_COORDINATE class Selection; -#endif // ENABLE_WORLD_COORDINATE class GLGizmoScale3D : public GLGizmoBase { @@ -23,28 +17,17 @@ class GLGizmoScale3D : public GLGizmoBase bool ctrl_down{ false }; Vec3d scale{ Vec3d::Ones() }; Vec3d drag_position{ Vec3d::Zero() }; -#if ENABLE_WORLD_COORDINATE Vec3d center{ Vec3d::Zero() }; Vec3d instance_center{ Vec3d::Zero() }; -#endif // ENABLE_WORLD_COORDINATE + Vec3d constraint_position{ Vec3d::Zero() }; BoundingBoxf3 box; -#if !ENABLE_WORLD_COORDINATE - std::array pivots{ Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero() }; -#endif // !ENABLE_WORLD_COORDINATE }; BoundingBoxf3 m_bounding_box; -#if ENABLE_WORLD_COORDINATE Transform3d m_grabbers_transform; Vec3d m_center{ Vec3d::Zero() }; Vec3d m_instance_center{ Vec3d::Zero() }; -#else - Transform3d m_transform; - // Transforms grabbers offsets to the proper reference system (world for instances, instance for volumes) - Transform3d m_offsets_transform; -#endif // ENABLE_WORLD_COORDINATE Vec3d m_scale{ Vec3d::Ones() }; - Vec3d m_offset{ Vec3d::Zero() }; double m_snap_step{ 0.05 }; StartingData m_starting; @@ -67,11 +50,7 @@ public: void set_snap_step(double step) { m_snap_step = step; } const Vec3d& get_scale() const { return m_scale; } -#if ENABLE_WORLD_COORDINATE - void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; m_offset = Vec3d::Zero(); } -#else void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; } -#endif // ENABLE_WORLD_COORDINATE std::string get_tooltip() const override; @@ -102,6 +81,7 @@ private: void do_scale_uniform(const UpdateData& data); double calc_ratio(const UpdateData& data) const; + void update_render_data(); }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index fe7e1b4ea..5ff491d2d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -169,11 +169,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection) trafo.translation()(2) += shift_z; const Geometry::Transformation transformation{trafo}; -#if ENABLE_WORLD_COORDINATE const Transform3d instance_scaling_matrix_inverse = transformation.get_scaling_factor_matrix().inverse(); -#else - const Transform3d& instance_scaling_matrix_inverse = transformation.get_matrix(true, true, false, true).inverse(); -#endif // ENABLE_WORLD_COORDINATE const Camera& camera = wxGetApp().plater()->get_camera(); const Transform3d& view_matrix = camera.get_view_matrix(); shader->set_uniform("projection_matrix", camera.get_projection_matrix()); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 55bf57602..73a4cc439 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1700,6 +1700,10 @@ void ImGuiWrapper::init_font(bool compress) assert(rect->Width == icon_sz); assert(rect->Height == icon_sz); std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz); + if (raw_data.empty()) { + rect_id++; + continue; + } const ImU32* pIn = (ImU32*)raw_data.data(); for (int y = 0; y < icon_sz; y++) { ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X); diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 826dc2407..8115136a5 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -212,49 +212,6 @@ static coord_t brim_offset(const PrintObject &po, const ModelInstance &inst) return has_outer_brim ? scaled(brim_width + brim_separation) : 0; } -template -Polygon support_layers_chull (Points &pts, It from_lyr, It to_lyr) { - - size_t cap = 0; - for (auto it = from_lyr; it != to_lyr; ++it) { - for (const ExPolygon &expoly : (*it)->support_islands) - cap += expoly.contour.points.size(); - } - - pts.reserve(pts.size() + cap); - - for (auto it = from_lyr; it != to_lyr; ++it) { - for (const ExPolygon &expoly : (*it)->support_islands) - std::copy(expoly.contour.begin(), expoly.contour.end(), - std::back_inserter(pts)); - } - - Polygon ret = Geometry::convex_hull(pts); - - return ret; -} - -static void update_arrangepoly_fffprint(arrangement::ArrangePolygon &ret, - const PrintObject &po, - const ModelInstance &inst) -{ - auto laststep = po.last_completed_step(); - - coord_t infl = brim_offset(po, inst); - - if (laststep < posCount && laststep > posSupportMaterial) { - Points pts = std::move(ret.poly.contour.points); - Polygon poly = support_layers_chull(pts, - po.support_layers().begin(), - po.support_layers().end()); - - ret.poly.contour = std::move(poly); - ret.poly.holes = {}; - } - - ret.inflation = infl; -} - arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi) { arrangement::ArrangePolygon ap = get_arrange_poly(mi, m_plater); @@ -442,7 +399,7 @@ arrangement::ArrangePolygon get_arrange_poly(ModelInstance *inst, plater->fff_print().get_print_object_by_model_object_id(obj_id); if (po) { - update_arrangepoly_fffprint(ap, *po, *inst); + ap.inflation = brim_offset(*po, *inst); } } diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 1765789b9..59be6cabb 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -436,11 +436,7 @@ std::vector MeshRaycaster::get_unobscured_idxs(const Geometry::Transfo { std::vector out; -#if ENABLE_WORLD_COORDINATE const Transform3d instance_matrix_no_translation_no_scaling = trafo.get_rotation_matrix(); -#else - const Transform3d& instance_matrix_no_translation_no_scaling = trafo.get_matrix(true,false,true); -#endif // ENABLE_WORLD_COORDINATE Vec3d direction_to_camera = -camera.get_dir_forward(); Vec3d direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse() * direction_to_camera).normalized().eval(); direction_to_camera_mesh = direction_to_camera_mesh.cwiseProduct(trafo.get_scaling_factor()); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 159a9693d..5bea120ec 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -64,9 +64,7 @@ #include "GUI_ObjectManipulation.hpp" #include "GUI_ObjectLayers.hpp" #include "GUI_Utils.hpp" -#if ENABLE_WORLD_COORDINATE #include "GUI_Geometry.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "GUI_Factories.hpp" #include "wxExtensions.hpp" #include "MainFrame.hpp" @@ -1548,10 +1546,8 @@ void Sidebar::update_mode() wxWindowUpdateLocker noUpdates(this); -#if ENABLE_WORLD_COORDINATE if (m_mode == comSimple) p->object_manipulation->set_coordinates_type(ECoordinatesType::World); -#endif // ENABLE_WORLD_COORDINATE p->object_list->get_sizer()->Show(m_mode > comSimple); @@ -2117,9 +2113,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this); view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); }); -#if ENABLE_WORLD_COORDINATE view3D_canvas->Bind(EVT_GLCANVAS_RESET_SKEW, [this](SimpleEvent&) { update(); }); -#endif // ENABLE_WORLD_COORDINATE view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); }); view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event& evt) { this->sidebar->enable_buttons(evt.data); }); view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this); @@ -3544,11 +3538,7 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const new_volume->set_type(old_volume->type()); new_volume->set_material_id(old_volume->material_id()); new_volume->set_transformation(old_volume->get_transformation()); -#if ENABLE_WORLD_COORDINATE new_volume->translate(new_volume->get_transformation().get_matrix_no_offset() * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); -#else - new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); -#endif // ENABLE_WORLD_COORDINATE assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters); if (old_volume->source.is_converted_from_inches) new_volume->convert_from_imperial_units(); @@ -3829,19 +3819,12 @@ void Plater::priv::reload_from_disk() new_volume->config.apply(old_volume->config); new_volume->set_type(old_volume->type()); new_volume->set_material_id(old_volume->material_id()); -#if ENABLE_WORLD_COORDINATE new_volume->set_transformation( old_volume->get_transformation().get_matrix() * old_volume->source.transform.get_matrix_no_offset() * Geometry::translation_transform(new_volume->source.mesh_offset - old_volume->source.mesh_offset) * new_volume->source.transform.get_matrix_no_offset().inverse() ); -#else - new_volume->set_transformation(Geometry::assemble_transform(old_volume->source.transform.get_offset()) * - old_volume->get_transformation().get_matrix(true) * - old_volume->source.transform.get_matrix(true)); - new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset)); -#endif // ENABLE_WORLD_COORDINATE new_volume->source.object_idx = old_volume->source.object_idx; new_volume->source.volume_idx = old_volume->source.volume_idx; assert(!old_volume->source.is_converted_from_inches || !old_volume->source.is_converted_from_meters); @@ -4370,11 +4353,7 @@ void Plater::priv::on_right_click(RBtnEvent& evt) const bool is_some_full_instances = selection.is_single_full_instance() || selection.is_single_full_object() || selection.is_multiple_full_instance(); -#if ENABLE_WORLD_COORDINATE const bool is_part = selection.is_single_volume_or_modifier() && ! selection.is_any_connector(); -#else - const bool is_part = selection.is_single_volume() || selection.is_single_modifier(); -#endif // ENABLE_WORLD_COORDINATE if (is_some_full_instances) menu = printer_technology == ptSLA ? menus.sla_object_menu() : menus.object_menu(); else if (is_part) @@ -4672,11 +4651,7 @@ bool Plater::priv::layers_height_allowed() const bool Plater::priv::can_mirror() const { -#if ENABLE_WORLD_COORDINATE return !sidebar->obj_list()->has_selected_cut_object(); -#else - return !sidebar->obj_list()->has_selected_cut_object() && get_selection().is_from_single_instance(); -#endif // ENABLE_WORLD_COORDINATE } diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index b6881f1ae..ecd8e0727 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -13,6 +13,11 @@ #include #include #include + +#include // include before devpropdef.h +#include +#include +#include #else // unix, linux & OSX includes #include @@ -73,6 +78,287 @@ std::vector RemovableDriveManager::search_for_removable_drives() cons } namespace { +int eject_alt(const std::wstring& volume_access_path) +{ + HANDLE handle = CreateFileW(volume_access_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed (handle == INVALID_HANDLE_VALUE): " << GetLastError(); + return 1; + } + DWORD deviceControlRetVal(0); + //these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger. + //sd cards does trigger WM_DEVICECHANGE messege, usb drives dont + BOOL e1 = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + BOOST_LOG_TRIVIAL(debug) << "FSCTL_LOCK_VOLUME " << e1 << " ; " << deviceControlRetVal << " ; " << GetLastError(); + BOOL e2 = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + BOOST_LOG_TRIVIAL(debug) << "FSCTL_DISMOUNT_VOLUME " << e2 << " ; " << deviceControlRetVal << " ; " << GetLastError(); + + // some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here with FALSE as third parameter, which should set PreventMediaRemoval + BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr); + if (error == 0) { + CloseHandle(handle); + BOOST_LOG_TRIVIAL(error) << "Alt Ejecting " << volume_access_path << " failed (IOCTL_STORAGE_EJECT_MEDIA)" << deviceControlRetVal << " " << GetLastError(); + return 1; + } + CloseHandle(handle); + BOOST_LOG_TRIVIAL(info) << "Alt Ejecting finished"; + return 0; +} + + +// From https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview +typedef struct _STRING_DESCRIPTOR_NODE +{ + struct _STRING_DESCRIPTOR_NODE* Next; + UCHAR DescriptorIndex; + USHORT LanguageID; + USB_STRING_DESCRIPTOR StringDescriptor[1]; +} STRING_DESCRIPTOR_NODE, * PSTRING_DESCRIPTOR_NODE; + +// Based at https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview +PSTRING_DESCRIPTOR_NODE GetStringDescriptor( + HANDLE handle_hub_device, + ULONG connection_index, + UCHAR descriptor_index, + USHORT language_ID +) +{ + BOOL success = 0; + ULONG nbytes = 0; + ULONG nbytes_returned = 0; + UCHAR string_desc_req_buf[sizeof(USB_DESCRIPTOR_REQUEST) + MAXIMUM_USB_STRING_LENGTH]; + PUSB_DESCRIPTOR_REQUEST string_desc_req = NULL; + PUSB_STRING_DESCRIPTOR string_desc = NULL; + PSTRING_DESCRIPTOR_NODE string_desc_node = NULL; + + nbytes = sizeof(string_desc_req_buf); + string_desc_req = (PUSB_DESCRIPTOR_REQUEST)string_desc_req_buf; + string_desc = (PUSB_STRING_DESCRIPTOR)(string_desc_req + 1); + + // Zero fill the entire request structure + memset(string_desc_req, 0, nbytes); + + // Indicate the port from which the descriptor will be requested + string_desc_req->ConnectionIndex = connection_index; + + // USBHUB uses URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE to process this + // IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION request. + // + // USBD will automatically initialize these fields: + // bmRequest = 0x80 + // bRequest = 0x06 + // + // We must inititialize these fields: + // wValue = Descriptor Type (high) and Descriptor Index (low byte) + // wIndex = Zero (or Language ID for String Descriptors) + // wLength = Length of descriptor buffer + string_desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) + | descriptor_index; + string_desc_req->SetupPacket.wIndex = language_ID; + string_desc_req->SetupPacket.wLength = (USHORT)(nbytes - sizeof(USB_DESCRIPTOR_REQUEST)); + + // Now issue the get descriptor request. + success = DeviceIoControl(handle_hub_device, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + string_desc_req, + nbytes, + string_desc_req, + nbytes, + &nbytes_returned, + NULL); + + // Do some sanity checks on the return from the get descriptor request. + if (!success) { + return NULL; + } + if (nbytes_returned < 2) { + return NULL; + } + if (string_desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE) { + return NULL; + } + if (string_desc->bLength != nbytes_returned - sizeof(USB_DESCRIPTOR_REQUEST)) { + return NULL; + } + if (string_desc->bLength % 2 != 0) { + return NULL; + } + + // Looks good, allocate some (zero filled) space for the string descriptor + // node and copy the string descriptor to it. + string_desc_node = (PSTRING_DESCRIPTOR_NODE)malloc(sizeof(STRING_DESCRIPTOR_NODE) + string_desc->bLength * sizeof(DWORD)); + if (string_desc_node == NULL) { + return NULL; + } + string_desc_node->Next = NULL; + string_desc_node->DescriptorIndex = descriptor_index; + string_desc_node->LanguageID = language_ID; + + memcpy(string_desc_node->StringDescriptor, + string_desc, + string_desc->bLength); + + return string_desc_node; +} + +// Based at https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview +HRESULT GetStringDescriptors( + _In_ HANDLE handle_hub_device, + _In_ ULONG connection_index, + _In_ UCHAR descriptor_index, + _In_ ULONG num_language_IDs, + _In_reads_(num_language_IDs) USHORT* language_IDs, + _In_ PSTRING_DESCRIPTOR_NODE string_desc_node_head, + std::wstring& result +) +{ + PSTRING_DESCRIPTOR_NODE tail = NULL; + PSTRING_DESCRIPTOR_NODE trailing = NULL; + ULONG i = 0; + + // Go to the end of the linked list, searching for the requested index to + // see if we've already retrieved it + for (tail = string_desc_node_head; tail != NULL; tail = tail->Next) { + if (tail->DescriptorIndex == descriptor_index) { + // copy string descriptor to result + for(int i = 0; i < tail->StringDescriptor->bLength / 2 - 1; i++) { + result += tail->StringDescriptor->bString[i]; + } + return S_OK; + } + trailing = tail; + } + tail = trailing; + + // Get the next String Descriptor. If this is NULL, then we're done (return) + // Otherwise, loop through all Language IDs + for (i = 0; (tail != NULL) && (i < num_language_IDs); i++) { + tail->Next = GetStringDescriptor(handle_hub_device, + connection_index, + descriptor_index, + language_IDs[i]); + tail = tail->Next; + } + + if (tail == NULL) { + return E_FAIL; + } else { + // copy string descriptor to result + for (int i = 0; i < tail->StringDescriptor->bLength / 2 - 1; i++) { + result += tail->StringDescriptor->bString[i]; + } + return S_OK; + } +} + +bool get_handle_from_devinst(DEVINST devinst, HANDLE& handle) +{ + // create path consisting of device id and guid + wchar_t device_id[MAX_PATH]; + CM_Get_Device_ID(devinst, device_id, MAX_PATH, 0); + + //convert device id string to device path - https://stackoverflow.com/a/32641140/981766 + std::wstring dev_id_wstr(device_id); + dev_id_wstr = std::regex_replace(dev_id_wstr, std::wregex(LR"(\\)"), L"#"); // '\' is special for regex + dev_id_wstr = std::regex_replace(dev_id_wstr, std::wregex(L"^"), LR"(\\?\)", std::regex_constants::format_first_only); + dev_id_wstr = std::regex_replace(dev_id_wstr, std::wregex(L"$"), L"#", std::regex_constants::format_first_only); + + // guid + wchar_t guid_wchar[64];//guid is 32 chars+4 hyphens+2 paranthesis+null => 64 should be more than enough + StringFromGUID2(GUID_DEVINTERFACE_USB_HUB, guid_wchar, 64); + dev_id_wstr.append(guid_wchar); + + // get handle + std::wstring& usb_hub_path = dev_id_wstr; + handle = CreateFileW(usb_hub_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (handle == INVALID_HANDLE_VALUE) { + // Sometimes device is not GUID_DEVINTERFACE_USB_HUB, than we need to check parent recursively + DEVINST parent_devinst = 0; + if (CM_Get_Parent(&parent_devinst, devinst, 0) != CR_SUCCESS) + return false; + return get_handle_from_devinst(parent_devinst, handle); + } + return true; +} + +// Read Configuration Descriptor - configuration string indexed by iConfiguration and decide if card reader +bool is_card_reader(HDEVINFO h_dev_info, SP_DEVINFO_DATA& spdd) +{ + // First get port number of device. + + DEVINST parent_devinst = 0; + HANDLE handle; // usb hub handle + DWORD usb_port_number = 0; + DWORD required_size = 0; + // First we need handle for GUID_DEVINTERFACE_USB_HUB device. + if (CM_Get_Parent(&parent_devinst, spdd.DevInst, 0) != CR_SUCCESS) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get parent DEVINST."; + return false; + } + if(!get_handle_from_devinst(parent_devinst, handle) || handle == INVALID_HANDLE_VALUE) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get HANDLE for parent DEVINST."; + return false; + } + // Get port number to which the usb device is attached on the hub. + if (SetupDiGetDeviceRegistryProperty(h_dev_info, &spdd, SPDRP_ADDRESS, nullptr, (PBYTE)&usb_port_number, sizeof(usb_port_number), &required_size) == 0) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get port number."; + return false; + } + + // Fill USB request packet to get iConfiguration value. + + int buffer_size = sizeof(USB_DESCRIPTOR_REQUEST) + sizeof(USB_CONFIGURATION_DESCRIPTOR); + BYTE* buffer = new BYTE[buffer_size]; + USB_DESCRIPTOR_REQUEST* request_packet = (USB_DESCRIPTOR_REQUEST*)buffer; + USB_CONFIGURATION_DESCRIPTOR* configuration_descriptor = (USB_CONFIGURATION_DESCRIPTOR*)((BYTE*)buffer + sizeof(USB_DESCRIPTOR_REQUEST)); + DWORD bytes_returned = 0; + // Fill information in packet. + request_packet->SetupPacket.bmRequest = 0x80; + request_packet->SetupPacket.bRequest = USB_REQUEST_GET_CONFIGURATION; + request_packet->ConnectionIndex = usb_port_number; + request_packet->SetupPacket.wValue = (USB_CONFIGURATION_DESCRIPTOR_TYPE << 8 | 0 /*Since only 1 device descriptor => index : 0*/); + request_packet->SetupPacket.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); + // Issue ioctl. + if (DeviceIoControl(handle, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, buffer, buffer_size, buffer, buffer_size, &bytes_returned, nullptr) == 0) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get Configuration Descriptor."; + return false; + } + // Nothing to read. + if (configuration_descriptor->iConfiguration == 0) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: iConfiguration value is 0."; + return false; + } + + // Get string descriptor and read string on address given by iConfiguration index . + // Based at https://github.com/microsoft/Windows-driver-samples/tree/main/usb/usbview + + PSTRING_DESCRIPTOR_NODE supported_languages_string = NULL; + ULONG num_language_IDs = 0; + USHORT* language_IDs = NULL; + std::wstring configuration_string; + // Get languages. + supported_languages_string = GetStringDescriptor(handle, usb_port_number, 0, 0); + if (supported_languages_string == NULL) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get language string descriptor."; + return false; + } + num_language_IDs = (supported_languages_string->StringDescriptor->bLength - 2) / 2; + language_IDs = (USHORT*)&supported_languages_string->StringDescriptor->bString[0]; + // Get configration string. + if (GetStringDescriptors(handle, usb_port_number, configuration_descriptor->iConfiguration, num_language_IDs, language_IDs, supported_languages_string, configuration_string) == E_FAIL) { + BOOST_LOG_TRIVIAL(warning) << "is_card_reader failed: Couldn't get configuration string descriptor."; + return false; + } + + // Final compare. + BOOST_LOG_TRIVIAL(error) << "Ejecting information: Retrieved configuration string: " << configuration_string; + if (configuration_string.find(L"CARD READER") != std::wstring::npos) { + BOOST_LOG_TRIVIAL(info) << "Detected external reader."; + return true; + } + return false; +} + // returns the device instance handle of a storage volume or 0 on error // called from eject_inner, based on https://stackoverflow.com/a/58848961 DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, WCHAR* dos_device_name) @@ -80,7 +366,7 @@ DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, WCHAR bool is_floppy = (wcsstr(dos_device_name, L"\\Floppy") != NULL); // TODO: could be tested better? if (drive_type != DRIVE_REMOVABLE || is_floppy) { - BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Drive is not removable."; + BOOST_LOG_TRIVIAL(warning) << "get_dev_inst_by_device_number failed: Drive is not removable."; return 0; } @@ -89,7 +375,7 @@ DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, WCHAR HDEVINFO h_dev_info = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (h_dev_info == INVALID_HANDLE_VALUE) { - BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Invalid dev info handle."; + BOOST_LOG_TRIVIAL(warning) << "get_dev_inst_by_device_number failed: Invalid dev info handle."; return 0; } @@ -135,13 +421,16 @@ DEVINST get_dev_inst_by_device_number(long device_number, UINT drive_type, WCHAR if (device_number != (long)sdn.DeviceNumber) { continue; } - // this is the drive, return the device instance + + // check if is sd card reader - if yes, indicate by returning invalid value. + bool reader = is_card_reader(h_dev_info, spdd); + SetupDiDestroyDeviceInfoList(h_dev_info); - return spdd.DevInst; + return !reader ? spdd.DevInst : 0; } SetupDiDestroyDeviceInfoList(h_dev_info); - BOOST_LOG_TRIVIAL(debug) << "get_dev_inst_by_device_number failed: Enmurating couldn't find the drive."; + BOOST_LOG_TRIVIAL(warning) << "get_dev_inst_by_device_number failed: Enmurating couldn't find the drive."; return 0; } @@ -194,10 +483,9 @@ int eject_inner(const std::string& path) // get the device instance handle of the storage volume by means of a SetupDi enum and matching the device number DEVINST dev_inst = get_dev_inst_by_device_number(device_number, drive_type, dos_device_name); - if (dev_inst == 0) { - BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1% has failed: Invalid device instance handle.", path); - return 1; + BOOST_LOG_TRIVIAL(error) << GUI::format("Ejecting of %1%: Invalid device instance handle. Going to try alternative ejecting method.", path); + return eject_alt(volume_access_path); } PNP_VETO_TYPE veto_type = PNP_VetoTypeUnknown; @@ -249,7 +537,7 @@ int eject_inner(const std::string& path) return 1; } -} +} // namespace // Called from UI therefore it blocks the UI thread. // It also blocks updates at the worker thread. // Win32 implementation. @@ -268,18 +556,21 @@ void RemovableDriveManager::eject_drive() if (it_drive_data != m_current_drives.end()) { if (!eject_inner(m_last_save_path)) { // success - assert(m_callback_evt_handler); - if (m_callback_evt_handler) - wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true))); + BOOST_LOG_TRIVIAL(info) << "Ejecting has succeeded."; + assert(m_callback_evt_handler); + if (m_callback_evt_handler) + wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true))); } else { // failed to eject // this should not happen, throwing exception might be the way here + BOOST_LOG_TRIVIAL(error) << "Ejecting has failed."; assert(m_callback_evt_handler); if (m_callback_evt_handler) wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair(*it_drive_data, false))); } } else { // drive not found in m_current_drives + BOOST_LOG_TRIVIAL(error) << "Ejecting has failed. Drive not found in m_current_drives."; assert(m_callback_evt_handler); if (m_callback_evt_handler) wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair({"",""}, false))); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 28cf367fd..608267720 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -9,9 +9,7 @@ #include "GUI_ObjectList.hpp" #include "Camera.hpp" #include "Plater.hpp" -#if ENABLE_WORLD_COORDINATE #include "MsgDialog.hpp" -#endif // ENABLE_WORLD_COORDINATE #include "Gizmos/GLGizmoBase.hpp" @@ -40,18 +38,11 @@ Selection::VolumeCache::TransformCache::TransformCache(const Geometry::Transform , scaling_factor(transform.get_scaling_factor()) , mirror(transform.get_mirror()) , full_matrix(transform.get_matrix()) -#if ENABLE_WORLD_COORDINATE , transform(transform) , rotation_matrix(transform.get_rotation_matrix()) , scale_matrix(transform.get_scaling_factor_matrix()) , mirror_matrix(transform.get_mirror_matrix()) -#endif // ENABLE_WORLD_COORDINATE { -#if !ENABLE_WORLD_COORDINATE - rotation_matrix = Geometry::assemble_transform(Vec3d::Zero(), rotation); - scale_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scaling_factor); - mirror_matrix = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), Vec3d::Ones(), mirror); -#endif // !ENABLE_WORLD_COORDINATE } Selection::VolumeCache::VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform) @@ -118,12 +109,10 @@ Selection::Selection() , m_scale_factor(1.0f) { this->set_bounding_boxes_dirty(); -#if ENABLE_WORLD_COORDINATE m_axes.set_stem_radius(0.5f); m_axes.set_stem_length(20.0f); m_axes.set_tip_radius(1.5f); m_axes.set_tip_length(5.0f); -#endif // ENABLE_WORLD_COORDINATE } @@ -595,11 +584,7 @@ bool Selection::is_sla_compliant() const bool Selection::is_single_text() const { -#if ENABLE_WORLD_COORDINATE if (!is_single_volume_or_modifier()) -#else - if (!is_single_volume() && !is_single_modifier()) -#endif // ENABLE_WORLD_COORDINATE return false; const GLVolume* gl_volume = (*m_volumes)[*m_list.begin()]; @@ -653,16 +638,6 @@ bool Selection::matches(const std::vector& volume_idxs) const return count == (unsigned int)m_list.size(); } -#if !ENABLE_WORLD_COORDINATE -bool Selection::requires_uniform_scale() const -{ - if (is_single_full_instance() || is_single_modifier() || is_single_volume()) - return false; - - return true; -} -#endif // !ENABLE_WORLD_COORDINATE - int Selection::get_object_idx() const { return (m_cache.content.size() == 1) ? m_cache.content.begin()->first : -1; @@ -721,11 +696,7 @@ const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const const GLVolume& volume = *(*m_volumes)[i]; if (volume.is_modifier) continue; -#if ENABLE_WORLD_COORDINATE Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix(); -#else - Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix(); -#endif // ENABLE_WORLD_COORDINATE trafo.translation().z() += volume.get_sla_shift_z(); (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo)); } @@ -755,7 +726,6 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const return *m_scaled_instance_bounding_box; } -#if ENABLE_WORLD_COORDINATE const BoundingBoxf3& Selection::get_full_unscaled_instance_bounding_box() const { assert(is_single_full_instance()); @@ -886,9 +856,7 @@ std::pair Selection::get_bounding_box_in_reference_s const Vec3d center = 0.5 * (min + max); out_trafo.set_offset(basis_trafo * center); return { out_box, out_trafo.get_matrix_no_scaling_factor() }; - } -#endif // ENABLE_WORLD_COORDINATE void Selection::setup_cache() { @@ -898,7 +866,6 @@ void Selection::setup_cache() set_caches(); } -#if ENABLE_WORLD_COORDINATE void Selection::translate(const Vec3d& displacement, TransformationType transformation_type) { if (!m_valid) @@ -947,50 +914,8 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor set_bounding_boxes_dirty(); wxGetApp().plater()->canvas3D()->requires_check_outside_state(); } -#else -void Selection::translate(const Vec3d& displacement, bool local) -{ - if (!m_valid) - return; - - EMode translation_type = m_mode; - - for (unsigned int i : m_list) { - GLVolume& v = *(*m_volumes)[i]; - if (m_mode == Volume || v.is_wipe_tower) { - if (local) - v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); - else { - const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement; - v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); - } - } - else if (m_mode == Instance) { - if (is_from_fully_selected_instance(i)) - v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement); - else { - const Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement; - v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); - translation_type = Volume; - } - } - } - -#if !DISABLE_INSTANCES_SYNCH - if (translation_type == Instance) - synchronize_unselected_instances(SyncRotationType::NONE); - else if (translation_type == Volume) - synchronize_unselected_volumes(); -#endif // !DISABLE_INSTANCES_SYNCH - - ensure_not_below_bed(); - set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); -} -#endif // ENABLE_WORLD_COORDINATE // Rotate an object around one of the axes. Only one rotation component is expected to be changing. -#if ENABLE_WORLD_COORDINATE void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) { if (!m_valid) @@ -1072,119 +997,6 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ set_bounding_boxes_dirty(); wxGetApp().plater()->canvas3D()->requires_check_outside_state(); } -#else -void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type) -{ - if (!m_valid) - return; - - // Only relative rotation values are allowed in the world coordinate system. - assert(!transformation_type.world() || transformation_type.relative()); - - if (!is_wipe_tower()) { - int rot_axis_max = 0; - if (rotation.isApprox(Vec3d::Zero())) { - for (unsigned int i : m_list) { - GLVolume &v = *(*m_volumes)[i]; - if (m_mode == Instance) { - v.set_instance_rotation(m_cache.volumes_data[i].get_instance_rotation()); - v.set_instance_offset(m_cache.volumes_data[i].get_instance_position()); - } - else if (m_mode == Volume) { - v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation()); - v.set_volume_offset(m_cache.volumes_data[i].get_volume_position()); - } - } - } - else { // this is not the wipe tower - //FIXME this does not work for absolute rotations (transformation_type.absolute() is true) - rotation.cwiseAbs().maxCoeff(&rot_axis_max); - -// if ( single instance or single volume ) - // Rotate around center , if only a single object or volume -// transformation_type.set_independent(); - - // For generic rotation, we want to rotate the first volume in selection, and then to synchronize the other volumes with it. - std::vector object_instance_first(m_model->objects.size(), -1); - auto rotate_instance = [this, &rotation, &object_instance_first, rot_axis_max, transformation_type](GLVolume &volume, int i) { - const int first_volume_idx = object_instance_first[volume.object_idx()]; - if (rot_axis_max != 2 && first_volume_idx != -1) { - // Generic rotation, but no rotation around the Z axis. - // Always do a local rotation (do not consider the selection to be a rigid body). - assert(is_approx(rotation.z(), 0.0)); - const GLVolume &first_volume = *(*m_volumes)[first_volume_idx]; - const Vec3d &rotation = first_volume.get_instance_rotation(); - const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[first_volume_idx].get_instance_rotation(), m_cache.volumes_data[i].get_instance_rotation()); - volume.set_instance_rotation(Vec3d(rotation.x(), rotation.y(), rotation.z() + z_diff)); - } - else { - // extracts rotations from the composed transformation - const Vec3d new_rotation = transformation_type.world() ? - Geometry::extract_rotation(Geometry::assemble_transform(Vec3d::Zero(), rotation) * m_cache.volumes_data[i].get_instance_rotation_matrix()) : - transformation_type.absolute() ? rotation : rotation + m_cache.volumes_data[i].get_instance_rotation(); - if (rot_axis_max == 2 && transformation_type.joint()) { - // Only allow rotation of multiple instances as a single rigid body when rotating around the Z axis. - const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), new_rotation); - volume.set_instance_offset(m_cache.dragging_center + Eigen::AngleAxisd(z_diff, Vec3d::UnitZ()) * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - } - volume.set_instance_rotation(new_rotation); - object_instance_first[volume.object_idx()] = i; - } - }; - - for (unsigned int i : m_list) { - GLVolume &v = *(*m_volumes)[i]; - if (is_single_full_instance()) - rotate_instance(v, i); - else if (is_single_volume() || is_single_modifier()) { - if (transformation_type.independent()) - v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation() + rotation); - else { - const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); - const Vec3d new_rotation = Geometry::extract_rotation(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - v.set_volume_rotation(new_rotation); - } - } - else { - if (m_mode == Instance) - rotate_instance(v, i); - else if (m_mode == Volume) { - // extracts rotations from the composed transformation - const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); - const Vec3d new_rotation = Geometry::extract_rotation(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - if (transformation_type.joint()) { - const Vec3d local_pivot = m_cache.volumes_data[i].get_instance_full_matrix().inverse() * m_cache.dragging_center; - const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() - local_pivot); - v.set_volume_offset(local_pivot + offset); - } - v.set_volume_rotation(new_rotation); - } - } - } - } - -#if !DISABLE_INSTANCES_SYNCH - if (m_mode == Instance) - synchronize_unselected_instances((rot_axis_max == 2) ? SyncRotationType::NONE : SyncRotationType::GENERAL); - else if (m_mode == Volume) - synchronize_unselected_volumes(); -#endif // !DISABLE_INSTANCES_SYNCH - } - else { // it's the wipe tower that's selected and being rotated - GLVolume& volume = *((*m_volumes)[*m_list.begin()]); // the wipe tower is always alone in the selection - - // make sure the wipe tower rotates around its center, not origin - // we can assume that only Z rotation changes - const Vec3d center_local = volume.transformed_bounding_box().center() - volume.get_volume_offset(); - const Vec3d center_local_new = Eigen::AngleAxisd(rotation.z()-volume.get_volume_rotation().z(), Vec3d::UnitZ()) * center_local; - volume.set_volume_rotation(rotation); - volume.set_volume_offset(volume.get_volume_offset() + center_local - center_local_new); - } - - set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); -} -#endif // ENABLE_WORLD_COORDINATE void Selection::flattening_rotate(const Vec3d& normal) { @@ -1199,21 +1011,11 @@ void Selection::flattening_rotate(const Vec3d& normal) for (unsigned int i : m_list) { GLVolume& v = *(*m_volumes)[i]; // Normal transformed from the object coordinate space to the world coordinate space. -#if ENABLE_WORLD_COORDINATE const Geometry::Transformation& old_inst_trafo = v.get_instance_transformation(); const Vec3d tnormal = old_inst_trafo.get_matrix().matrix().block(0, 0, 3, 3).inverse().transpose() * normal; // Additional rotation to align tnormal with the down vector in the world coordinate space. const Transform3d rotation_matrix = Transform3d(Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ())); v.set_instance_transformation(old_inst_trafo.get_offset_matrix() * rotation_matrix * old_inst_trafo.get_matrix_no_offset()); -#else - const auto& voldata = m_cache.volumes_data[i]; - Vec3d tnormal = (Geometry::assemble_transform( - Vec3d::Zero(), voldata.get_instance_rotation(), - voldata.get_instance_scaling_factor().cwiseInverse(), voldata.get_instance_mirror()) * normal).normalized(); - // Additional rotation to align tnormal with the down vector in the world coordinate space. - auto extra_rotation = Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ()); - v.set_instance_rotation(Geometry::extract_rotation(extra_rotation.toRotationMatrix() * m_cache.volumes_data[i].get_instance_rotation_matrix())); -#endif // ENABLE_WORLD_COORDINATE } #if !DISABLE_INSTANCES_SYNCH @@ -1226,79 +1028,10 @@ void Selection::flattening_rotate(const Vec3d& normal) this->set_bounding_boxes_dirty(); } -#if ENABLE_WORLD_COORDINATE void Selection::scale(const Vec3d& scale, TransformationType transformation_type) { scale_and_translate(scale, Vec3d::Zero(), transformation_type); } -#else -void Selection::scale(const Vec3d& scale, TransformationType transformation_type) -{ - if (!m_valid) - return; - - for (unsigned int i : m_list) { - GLVolume &v = *(*m_volumes)[i]; - if (is_single_full_instance()) { - if (transformation_type.relative()) { - const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); - const Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3); - // extracts scaling factors from the composed transformation - const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (transformation_type.joint()) - v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - - v.set_instance_scaling_factor(new_scale); - } - else { - if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) { - // Non-uniform scaling. Transform the scaling factors into the local coordinate system. - // This is only possible, if the instance rotation is mulitples of ninety degrees. - assert(Geometry::is_rotation_ninety_degrees(v.get_instance_rotation())); - v.set_instance_scaling_factor((v.get_instance_transformation().get_matrix(true, false, true, true).matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs()); - } - else - v.set_instance_scaling_factor(scale); - } - } - else if (is_single_volume() || is_single_modifier()) - v.set_volume_scaling_factor(scale); - else { - const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); - if (m_mode == Instance) { - const Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3); - // extracts scaling factors from the composed transformation - const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (transformation_type.joint()) - v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center)); - - v.set_instance_scaling_factor(new_scale); - } - else if (m_mode == Volume) { - const Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3); - // extracts scaling factors from the composed transformation - const Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (transformation_type.joint()) { - const Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); - v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); - } - v.set_volume_scaling_factor(new_scale); - } - } - } - -#if !DISABLE_INSTANCES_SYNCH - if (m_mode == Instance) - synchronize_unselected_instances(SyncRotationType::NONE); - else if (m_mode == Volume) - synchronize_unselected_volumes(); -#endif // !DISABLE_INSTANCES_SYNCH - - ensure_on_bed(); - set_bounding_boxes_dirty(); - wxGetApp().plater()->canvas3D()->requires_check_outside_state(); -} -#endif // ENABLE_WORLD_COORDINATE void Selection::scale_to_fit_print_volume(const BuildVolume& volume) { @@ -1322,13 +1055,9 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) // center selection on print bed setup_cache(); offset.z() = -get_bounding_box().min.z(); -#if ENABLE_WORLD_COORDINATE TransformationType trafo_type; trafo_type.set_relative(); translate(offset, trafo_type); -#else - translate(offset); -#endif // ENABLE_WORLD_COORDINATE wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot wxGetApp().obj_manipul()->set_dirty(); @@ -1435,39 +1164,13 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) } } -#if ENABLE_WORLD_COORDINATE void Selection::mirror(Axis axis, TransformationType transformation_type) { const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0); scale_and_translate(mirror, Vec3d::Zero(), transformation_type); } -#else -void Selection::mirror(Axis axis) -{ - if (!m_valid) - return; - for (unsigned int i : m_list) { - GLVolume& v = *(*m_volumes)[i]; - if (is_single_full_instance()) - v.set_instance_mirror(axis, -v.get_instance_mirror(axis)); - else if (m_mode == Volume) - v.set_volume_mirror(axis, -v.get_volume_mirror(axis)); - } - -#if !DISABLE_INSTANCES_SYNCH - if (m_mode == Instance) - synchronize_unselected_instances(SyncRotationType::NONE); - else if (m_mode == Volume) - synchronize_unselected_volumes(); -#endif // !DISABLE_INSTANCES_SYNCH - - set_bounding_boxes_dirty(); -} -#endif // ENABLE_WORLD_COORDINATE - -#if ENABLE_WORLD_COORDINATE -void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type) +void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type) { if (!m_valid) return; @@ -1501,32 +1204,28 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot; Matrix3d inst_rotation, inst_scale; inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale); - const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + inst_rotation * translation); + const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + world_translation); const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale); v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot)); } else - transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); + transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); } else { if (!is_single_volume_or_modifier()) { assert(transformation_type.world()); - transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center); + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(scale), m_cache.dragging_center); } else { - if (transformation_type.local() && transformation_type.absolute()) { - const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform(); - Matrix3d vol_rotation, vol_scale; - vol_trafo.get_matrix().computeRotationScaling(&vol_rotation, &vol_scale); - const Transform3d offset_trafo = Geometry::translation_transform(vol_trafo.get_offset() + vol_rotation * translation); - const Transform3d scale_trafo = Transform3d(vol_scale) * Geometry::scale_transform(scale); - v.set_volume_transformation(offset_trafo * Transform3d(vol_rotation) * scale_trafo); - } - else { - transformation_type.set_independent(); - transformation_type.set_relative(); - transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center); - } + transformation_type.set_independent(); + Vec3d translation; + if (transformation_type.local()) + translation = volume_data.get_volume_transform().get_matrix_no_offset().inverse() * inst_trafo.get_matrix_no_offset().inverse() * world_translation; + else if (transformation_type.instance()) + translation = inst_trafo.get_matrix_no_offset().inverse() * world_translation; + else + translation = world_translation; + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center); } } } @@ -1604,50 +1303,6 @@ void Selection::reset_skew() set_bounding_boxes_dirty(); wxGetApp().plater()->canvas3D()->requires_check_outside_state(); } -#else -void Selection::translate(unsigned int object_idx, const Vec3d& displacement) -{ - if (!m_valid) - return; - - for (unsigned int i : m_list) { - GLVolume& v = *(*m_volumes)[i]; - if (v.object_idx() == (int)object_idx) - v.set_instance_offset(v.get_instance_offset() + displacement); - } - - std::set done; // prevent processing volumes twice - done.insert(m_list.begin(), m_list.end()); - - for (unsigned int i : m_list) { - if (done.size() == m_volumes->size()) - break; - - if ((*m_volumes)[i]->is_wipe_tower) - continue; - - int object_idx = (*m_volumes)[i]->object_idx(); - - // Process unselected volumes of the object. - for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { - if (done.size() == m_volumes->size()) - break; - - if (done.find(j) != done.end()) - continue; - - GLVolume& v = *(*m_volumes)[j]; - if (v.object_idx() != object_idx) - continue; - - v.set_instance_offset(v.get_instance_offset() + displacement); - done.insert(j); - } - } - - this->set_bounding_boxes_dirty(); -} -#endif // ENABLE_WORLD_COORDINATE void Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement) { @@ -1657,11 +1312,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co for (unsigned int i : m_list) { GLVolume& v = *(*m_volumes)[i]; if (v.object_idx() == (int)object_idx && v.instance_idx() == (int)instance_idx) -#if ENABLE_WORLD_COORDINATE v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix()); -#else - v.set_instance_offset(v.get_instance_offset() + displacement); -#endif // ENABLE_WORLD_COORDINATE } std::set done; // prevent processing volumes twice @@ -1688,11 +1339,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co if (v.object_idx() != object_idx || v.instance_idx() != (int)instance_idx) continue; -#if ENABLE_WORLD_COORDINATE v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix()); -#else - v.set_instance_offset(v.get_instance_offset() + displacement); -#endif // ENABLE_WORLD_COORDINATE done.insert(j); } } @@ -1700,7 +1347,6 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co this->set_bounding_boxes_dirty(); } -#if ENABLE_WORLD_COORDINATE int Selection::bake_transform_if_needed() const { if ((is_single_full_instance() && wxGetApp().obj_manipul()->is_world_coordinates()) || @@ -1751,7 +1397,6 @@ int Selection::bake_transform_if_needed() const return 1; } -#endif // ENABLE_WORLD_COORDINATE void Selection::erase() { @@ -1865,12 +1510,8 @@ void Selection::render(float scale_factor) m_scale_factor = scale_factor; // render cumulative bounding box of selected volumes -#if ENABLE_WORLD_COORDINATE const auto& [box, trafo] = get_bounding_box_in_current_reference_system(); render_bounding_box(box, trafo, ColorRGB::WHITE()); -#else - render_bounding_box(get_bounding_box(), ColorRGB::WHITE()); -#endif // ENABLE_WORLD_COORDINATE render_synchronized_volumes(); } @@ -1919,39 +1560,15 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const Transform3d base_matrix = Geometry::translation_transform(get_bounding_box().center()); Transform3d orient_matrix = Transform3d::Identity(); -#if ENABLE_WORLD_COORDINATE const Vec3d center = get_bounding_box().center(); Vec3d axes_center = center; -#endif // ENABLE_WORLD_COORDINATE if (!boost::starts_with(sidebar_field, "layer")) { shader->set_uniform("emission_factor", 0.05f); -#if ENABLE_WORLD_COORDINATE if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) { orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix(); axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset(); -#else - const Vec3d& center = get_bounding_box().center(); - if (is_single_full_instance() && !wxGetApp().obj_manipul()->get_world_coordinates()) { - glsafe(::glTranslated(center.x(), center.y(), center.z())); - if (!boost::starts_with(sidebar_field, "position")) { - if (boost::starts_with(sidebar_field, "scale")) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::starts_with(sidebar_field, "rotation")) { - if (boost::ends_with(sidebar_field, "x")) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else if (boost::ends_with(sidebar_field, "y")) { - const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation(); - if (rotation.x() == 0.0) - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - else - orient_matrix.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ())); - } - } - } -#endif // ENABLE_WORLD_COORDINATE } -#if ENABLE_WORLD_COORDINATE else if (is_single_volume_or_modifier()) { if (!wxGetApp().obj_manipul()->is_world_coordinates()) { if (wxGetApp().obj_manipul()->is_local_coordinates()) { @@ -1964,32 +1581,18 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) axes_center = (*m_volumes)[*m_list.begin()]->get_instance_offset(); } } -#else - else if (is_single_volume() || is_single_modifier()) { - glsafe(::glTranslated(center.x(), center.y(), center.z())); - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); - if (!boost::starts_with(sidebar_field, "position")) - orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true); -#endif // ENABLE_WORLD_COORDINATE } else { if (requires_local_axes()) -#if ENABLE_WORLD_COORDINATE orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix(); -#else - orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); -#endif // ENABLE_WORLD_COORDINATE } } if (!boost::starts_with(sidebar_field, "layer")) glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); -#if ENABLE_WORLD_COORDINATE - if (!boost::starts_with(sidebar_field, "layer")) { + if (!boost::starts_with(sidebar_field, "layer")) shader->set_uniform("emission_factor", 0.1f); - } -#endif // ENABLE_WORLD_COORDINATE if (boost::starts_with(sidebar_field, "position")) render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix); @@ -2000,12 +1603,10 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) else if (boost::starts_with(sidebar_field, "layer")) render_sidebar_layers_hints(sidebar_field, *shader); -#if ENABLE_WORLD_COORDINATE if (!boost::starts_with(sidebar_field, "layer")) { if (wxGetApp().obj_manipul()->is_instance_coordinates()) m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f); } -#endif // ENABLE_WORLD_COORDINATE shader->stop_using(); } @@ -2446,11 +2047,9 @@ void Selection::render_synchronized_volumes() if (m_mode == Instance) return; -#if ENABLE_WORLD_COORDINATE const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type(); BoundingBoxf3 box; Transform3d trafo; -#endif // ENABLE_WORLD_COORDINATE for (unsigned int i : m_list) { const GLVolume& volume = *(*m_volumes)[i]; @@ -2464,7 +2063,6 @@ void Selection::render_synchronized_volumes() if (v.object_idx() != object_idx || v.volume_idx() != volume_idx) continue; -#if ENABLE_WORLD_COORDINATE if (coordinates_type == ECoordinatesType::World) { box = v.transformed_convex_hull_bounding_box(); trafo = Transform3d::Identity(); @@ -2478,18 +2076,11 @@ void Selection::render_synchronized_volumes() trafo = v.get_instance_transformation().get_matrix(); } render_bounding_box(box, trafo, ColorRGB::YELLOW()); -#else - render_bounding_box(v.transformed_convex_hull_bounding_box(), ColorRGB::YELLOW()); -#endif // ENABLE_WORLD_COORDINATE } } } -#if ENABLE_WORLD_COORDINATE void Selection::render_bounding_box(const BoundingBoxf3& box, const Transform3d& trafo, const ColorRGB& color) -#else -void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color) -#endif // ENABLE_WORLD_COORDINATE { const BoundingBoxf3& curr_box = m_box.get_bounding_box(); @@ -2586,11 +2177,7 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, const ColorRGB& co shader->start_using(); const Camera& camera = wxGetApp().plater()->get_camera(); -#if ENABLE_WORLD_COORDINATE shader->set_uniform("view_model_matrix", camera.get_view_matrix() * trafo); -#else - shader->set_uniform("view_model_matrix", camera.get_view_matrix()); -#endif // ENABLE_WORLD_COORDINATE shader->set_uniform("projection_matrix", camera.get_projection_matrix()); #if ENABLE_GL_CORE_PROFILE const std::array& viewport = camera.get_viewport(); @@ -2672,11 +2259,7 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field, void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix) { -#if ENABLE_WORLD_COORDINATE const bool uniform_scale = wxGetApp().obj_manipul()->get_uniform_scaling(); -#else - const bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); -#endif // ENABLE_WORLD_COORDINATE auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& view_matrix, const Transform3d& model_matrix) { m_arrow.set_color(uniform_scale ? UNIFORM_SCALE_COLOR : get_color(axis)); @@ -2808,7 +2391,7 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field, GL glsafe(::glDisable(GL_BLEND)); } -#if ENABLE_WORLD_COORDINATE_DEBUG +#if ENABLE_MATRICES_DEBUG void Selection::render_debug_window() const { if (m_list.empty()) @@ -2928,7 +2511,7 @@ void Selection::render_debug_window() const imgui.end(); } -#endif // ENABLE_WORLD_COORDINATE_DEBUG +#endif // ENABLE_MATRICES_DEBUG static bool is_left_handed(const Transform3d::ConstLinearPart& m) { @@ -3027,7 +2610,6 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV #endif /* NDEBUG */ -#if ENABLE_WORLD_COORDINATE void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type) { std::set done; // prevent processing volumes twice @@ -3076,69 +2658,6 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ verify_instances_rotation_synchronized(*m_model, *m_volumes); #endif /* NDEBUG */ } -#else -void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type) -{ - std::set done; // prevent processing volumes twice - done.insert(m_list.begin(), m_list.end()); - - for (unsigned int i : m_list) { - if (done.size() == m_volumes->size()) - break; - - const GLVolume* volume_i = (*m_volumes)[i]; - if (volume_i->is_wipe_tower) - continue; - - const int object_idx = volume_i->object_idx(); - const int instance_idx = volume_i->instance_idx(); - const Vec3d& rotation = volume_i->get_instance_rotation(); - const Vec3d& scaling_factor = volume_i->get_instance_scaling_factor(); - const Vec3d& mirror = volume_i->get_instance_mirror(); - - // Process unselected instances. - for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { - if (done.size() == m_volumes->size()) - break; - - if (done.find(j) != done.end()) - continue; - - GLVolume* volume_j = (*m_volumes)[j]; - if (volume_j->object_idx() != object_idx || volume_j->instance_idx() == instance_idx) - continue; - - assert(is_rotation_xy_synchronized(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation())); - - switch (sync_rotation_type) { - case SyncRotationType::NONE: { - // z only rotation -> synch instance z - // The X,Y rotations should be synchronized from start to end of the rotation. - assert(is_rotation_xy_synchronized(rotation, volume_j->get_instance_rotation())); - if (wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA) - volume_j->set_instance_offset(Z, volume_i->get_instance_offset().z()); - break; - } - case SyncRotationType::GENERAL: { - // generic rotation -> update instance z with the delta of the rotation. - const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()); - volume_j->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() + z_diff }); - break; - } - } - - volume_j->set_instance_scaling_factor(scaling_factor); - volume_j->set_instance_mirror(mirror); - - done.insert(j); - } - } - -#ifndef NDEBUG - verify_instances_rotation_synchronized(*m_model, *m_volumes); -#endif /* NDEBUG */ -} -#endif // ENABLE_WORLD_COORDINATE void Selection::synchronize_unselected_volumes() { @@ -3149,14 +2668,7 @@ void Selection::synchronize_unselected_volumes() const int object_idx = volume->object_idx(); const int volume_idx = volume->volume_idx(); -#if ENABLE_WORLD_COORDINATE const Geometry::Transformation& trafo = volume->get_volume_transformation(); -#else - const Vec3d& offset = volume->get_volume_offset(); - const Vec3d& rotation = volume->get_volume_rotation(); - const Vec3d& scaling_factor = volume->get_volume_scaling_factor(); - const Vec3d& mirror = volume->get_volume_mirror(); -#endif // ENABLE_WORLD_COORDINATE // Process unselected volumes. for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { @@ -3167,14 +2679,7 @@ void Selection::synchronize_unselected_volumes() if (v->object_idx() != object_idx || v->volume_idx() != volume_idx) continue; -#if ENABLE_WORLD_COORDINATE v->set_volume_transformation(trafo); -#else - v->set_volume_offset(offset); - v->set_volume_rotation(rotation); - v->set_volume_scaling_factor(scaling_factor); - v->set_volume_mirror(mirror); -#endif // ENABLE_WORLD_COORDINATE } } } @@ -3294,13 +2799,8 @@ void Selection::paste_volumes_from_clipboard() { ModelInstance* dst_instance = dst_object->instances[dst_inst_idx]; BoundingBoxf3 dst_instance_bb = dst_object->instance_bounding_box(dst_inst_idx); -#if ENABLE_WORLD_COORDINATE Transform3d src_matrix = src_object->instances[0]->get_transformation().get_matrix_no_offset(); Transform3d dst_matrix = dst_instance->get_transformation().get_matrix_no_offset(); -#else - Transform3d src_matrix = src_object->instances[0]->get_transformation().get_matrix(true); - Transform3d dst_matrix = dst_instance->get_transformation().get_matrix(true); -#endif // ENABLE_WORLD_COORDINATE bool from_same_object = (src_object->input_file == dst_object->input_file) && src_matrix.isApprox(dst_matrix); // used to keep relative position of multivolume selections when pasting from another object @@ -3378,7 +2878,6 @@ void Selection::paste_objects_from_clipboard() #endif /* _DEBUG */ } -#if ENABLE_WORLD_COORDINATE void Selection::transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, const Transform3d& transform, const Vec3d& world_pivot) { @@ -3420,7 +2919,6 @@ void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& v else assert(false); } -#endif // ENABLE_WORLD_COORDINATE ModelVolume *get_selected_volume(const Selection &selection) { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index d3f456702..6395afbd7 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -2,12 +2,8 @@ #define slic3r_GUI_Selection_hpp_ #include "libslic3r/Geometry.hpp" -#if ENABLE_WORLD_COORDINATE #include "GUI_Geometry.hpp" #include "CoordAxes.hpp" -#else -#include "GLModel.hpp" -#endif // ENABLE_WORLD_COORDINATE #include #include @@ -30,60 +26,6 @@ using ModelObjectPtrs = std::vector; namespace GUI { -#if !ENABLE_WORLD_COORDINATE -class TransformationType -{ -public: - enum Enum { - // Transforming in a world coordinate system - World = 0, - // Transforming in a local coordinate system - Local = 1, - // Absolute transformations, allowed in local coordinate system only. - Absolute = 0, - // Relative transformations, allowed in both local and world coordinate system. - Relative = 2, - // For group selection, the transformation is performed as if the group made a single solid body. - Joint = 0, - // For group selection, the transformation is performed on each object independently. - Independent = 4, - - World_Relative_Joint = World | Relative | Joint, - World_Relative_Independent = World | Relative | Independent, - Local_Absolute_Joint = Local | Absolute | Joint, - Local_Absolute_Independent = Local | Absolute | Independent, - Local_Relative_Joint = Local | Relative | Joint, - Local_Relative_Independent = Local | Relative | Independent, - }; - - TransformationType() : m_value(World) {} - TransformationType(Enum value) : m_value(value) {} - TransformationType& operator=(Enum value) { m_value = value; return *this; } - - Enum operator()() const { return m_value; } - bool has(Enum v) const { return ((unsigned int)m_value & (unsigned int)v) != 0; } - - void set_world() { this->remove(Local); } - void set_local() { this->add(Local); } - void set_absolute() { this->remove(Relative); } - void set_relative() { this->add(Relative); } - void set_joint() { this->remove(Independent); } - void set_independent() { this->add(Independent); } - - bool world() const { return !this->has(Local); } - bool local() const { return this->has(Local); } - bool absolute() const { return !this->has(Relative); } - bool relative() const { return this->has(Relative); } - bool joint() const { return !this->has(Independent); } - bool independent() const { return this->has(Independent); } - -private: - void add(Enum v) { m_value = Enum((unsigned int)m_value | (unsigned int)v); } - void remove(Enum v) { m_value = Enum((unsigned int)m_value & (~(unsigned int)v)); } - - Enum m_value; -}; -#endif // !ENABLE_WORLD_COORDINATE class Selection { @@ -126,9 +68,7 @@ private: Transform3d scale_matrix{ Transform3d::Identity() }; Transform3d mirror_matrix{ Transform3d::Identity() }; Transform3d full_matrix{ Transform3d::Identity() }; -#if ENABLE_WORLD_COORDINATE Geometry::Transformation transform; -#endif // ENABLE_WORLD_COORDINATE TransformCache() = default; explicit TransformCache(const Geometry::Transformation& transform); @@ -142,18 +82,11 @@ private: VolumeCache(const Geometry::Transformation& volume_transform, const Geometry::Transformation& instance_transform); const Vec3d& get_volume_position() const { return m_volume.position; } -#if !ENABLE_WORLD_COORDINATE - const Vec3d& get_volume_rotation() const { return m_volume.rotation; } - const Vec3d& get_volume_scaling_factor() const { return m_volume.scaling_factor; } - const Vec3d& get_volume_mirror() const { return m_volume.mirror; } -#endif // !ENABLE_WORLD_COORDINATE const Transform3d& get_volume_rotation_matrix() const { return m_volume.rotation_matrix; } const Transform3d& get_volume_scale_matrix() const { return m_volume.scale_matrix; } const Transform3d& get_volume_mirror_matrix() const { return m_volume.mirror_matrix; } const Transform3d& get_volume_full_matrix() const { return m_volume.full_matrix; } -#if ENABLE_WORLD_COORDINATE const Geometry::Transformation& get_volume_transform() const { return m_volume.transform; } -#endif // ENABLE_WORLD_COORDINATE const Vec3d& get_instance_position() const { return m_instance.position; } const Vec3d& get_instance_rotation() const { return m_instance.rotation; } @@ -163,9 +96,7 @@ private: const Transform3d& get_instance_scale_matrix() const { return m_instance.scale_matrix; } const Transform3d& get_instance_mirror_matrix() const { return m_instance.mirror_matrix; } const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; } -#if ENABLE_WORLD_COORDINATE const Geometry::Transformation& get_instance_transform() const { return m_instance.transform; } -#endif // ENABLE_WORLD_COORDINATE }; public: @@ -233,7 +164,6 @@ private: // Bounding box of a single full instance selection, in world coordinates. // Modifiers are NOT taken in account std::optional m_scaled_instance_bounding_box; -#if ENABLE_WORLD_COORDINATE // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied. // Modifiers are taken in account std::optional m_full_unscaled_instance_bounding_box; @@ -246,15 +176,12 @@ private: // Bounding box aligned to the axis of the currently selected reference system (World/Object/Part) // and transform to place and orient it in world coordinates std::optional> m_bounding_box_in_current_reference_system; -#endif // ENABLE_WORLD_COORDINATE #if ENABLE_RENDER_SELECTION_CENTER GLModel m_vbo_sphere; #endif // ENABLE_RENDER_SELECTION_CENTER -#if ENABLE_WORLD_COORDINATE CoordAxes m_axes; -#endif // ENABLE_WORLD_COORDINATE GLModel m_arrow; GLModel m_curved_arrow; GLModel m_box; @@ -329,9 +256,7 @@ public: bool is_from_single_object() const; bool is_sla_compliant() const; bool is_instance_mode() const { return m_mode == Instance; } -#if ENABLE_WORLD_COORDINATE bool is_single_volume_or_modifier() const { return is_single_volume() || is_single_modifier(); } -#endif // ENABLE_WORLD_COORDINATE bool is_single_volume_instance() const { return is_single_full_instance() && m_list.size() == 1; } bool is_single_text() const; @@ -345,7 +270,6 @@ public: // returns true if the selection contains all and only the given indices bool matches(const std::vector& volume_idxs) const; -#if ENABLE_WORLD_COORDINATE enum class EUniformScaleRequiredReason : unsigned char { NotRequired, @@ -354,9 +278,6 @@ public: VolumeNotAxisAligned_Instance, MultipleSelection, }; -#else - bool requires_uniform_scale() const; -#endif // ENABLE_WORLD_COORDINATE // Returns the the object id if the selection is from a single object, otherwise is -1 int get_object_idx() const; @@ -382,7 +303,6 @@ public: // Bounding box of a single full instance selection, in world coordinates. // Modifiers are NOT taken in account const BoundingBoxf3& get_scaled_instance_bounding_box() const; -#if ENABLE_WORLD_COORDINATE // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied. // Modifiers are taken in account const BoundingBoxf3& get_full_unscaled_instance_bounding_box() const; @@ -398,36 +318,24 @@ public: // Returns the bounding box aligned to the axes of the given reference system // and the transform to place and orient it in world coordinates std::pair get_bounding_box_in_reference_system(ECoordinatesType type) const; -#endif // ENABLE_WORLD_COORDINATE void setup_cache(); -#if ENABLE_WORLD_COORDINATE void translate(const Vec3d& displacement, TransformationType transformation_type); -#else - void translate(const Vec3d& displacement, bool local = false); -#endif // ENABLE_WORLD_COORDINATE void rotate(const Vec3d& rotation, TransformationType transformation_type); void flattening_rotate(const Vec3d& normal); void scale(const Vec3d& scale, TransformationType transformation_type); void scale_to_fit_print_volume(const BuildVolume& volume); -#if ENABLE_WORLD_COORDINATE - void scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type); + void scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type); void mirror(Axis axis, TransformationType transformation_type); void reset_skew(); -#else - void mirror(Axis axis); - void translate(unsigned int object_idx, const Vec3d& displacement); -#endif // ENABLE_WORLD_COORDINATE void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement); -#if ENABLE_WORLD_COORDINATE // returns: // -1 if the user refused to proceed with baking when asked // 0 if the baking was performed // 1 if no baking was needed int bake_transform_if_needed() const; -#endif // ENABLE_WORLD_COORDINATE void erase(); @@ -457,9 +365,9 @@ public: // returns the list of idxs of the objects which are in the selection std::set get_object_idxs() const; -#if ENABLE_WORLD_COORDINATE_DEBUG +#if ENABLE_MATRICES_DEBUG void render_debug_window() const; -#endif // ENABLE_WORLD_COORDINATE_DEBUG +#endif // ENABLE_MATRICES_DEBUG private: void update_valid(); @@ -470,7 +378,6 @@ private: void do_remove_volume(unsigned int volume_idx); void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); void do_remove_object(unsigned int object_idx); -#if ENABLE_WORLD_COORDINATE void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); @@ -478,15 +385,8 @@ private: m_full_unscaled_instance_local_bounding_box.reset(); m_bounding_box_in_current_reference_system.reset(); } -#else - void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); } -#endif // ENABLE_WORLD_COORDINATE void render_synchronized_volumes(); -#if ENABLE_WORLD_COORDINATE void render_bounding_box(const BoundingBoxf3& box, const Transform3d& trafo, const ColorRGB& color); -#else - void render_bounding_box(const BoundingBoxf3& box, const ColorRGB& color); -#endif // ENABLE_WORLD_COORDINATE void render_selected_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const; void render_sidebar_position_hints(const std::string& sidebar_field, GLShaderProgram& shader, const Transform3d& matrix); @@ -500,10 +400,8 @@ public: NONE = 0, // Synchronize after rotation by an axis not parallel with Z. GENERAL = 1, -#if ENABLE_WORLD_COORDINATE // Synchronize after rotation reset. RESET = 2 -#endif // ENABLE_WORLD_COORDINATE }; void synchronize_unselected_instances(SyncRotationType sync_rotation_type); void synchronize_unselected_volumes(); @@ -516,12 +414,10 @@ private: void paste_volumes_from_clipboard(); void paste_objects_from_clipboard(); -#if ENABLE_WORLD_COORDINATE void transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, const Transform3d& transform, const Vec3d& world_pivot); void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, const Transform3d& transform, const Vec3d& world_pivot); -#endif // ENABLE_WORLD_COORDINATE }; ModelVolume *get_selected_volume(const Selection &selection); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d31f48913..dd138530d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1122,10 +1122,11 @@ void Tab::update_wiping_button_visibility() { return; // ys_FIXME bool wipe_tower_enabled = dynamic_cast( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value; bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; + bool single_extruder_multi_material = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; auto wiping_dialog_button = wxGetApp().sidebar().get_wiping_dialog_button(); if (wiping_dialog_button) { - wiping_dialog_button->Show(wipe_tower_enabled && multiple_extruders); + wiping_dialog_button->Show(wipe_tower_enabled && multiple_extruders && single_extruder_multi_material); wiping_dialog_button->GetParent()->Layout(); } } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index a8da90024..1d2cda971 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -553,13 +553,7 @@ void LockButton::OnButton(wxCommandEvent& event) if (m_disabled) return; -#if ENABLE_WORLD_COORDINATE SetLock(!m_is_pushed); -#else - m_is_pushed = !m_is_pushed; - update_button_bitmaps(); -#endif // ENABLE_WORLD_COORDINATE - event.Skip(); } diff --git a/version.inc b/version.inc index 8a0b022c2..698bb3328 100644 --- a/version.inc +++ b/version.inc @@ -3,7 +3,7 @@ set(SLIC3R_APP_NAME "PrusaSlicer") set(SLIC3R_APP_KEY "PrusaSlicer") -set(SLIC3R_VERSION "2.6.0-alpha5") +set(SLIC3R_VERSION "2.6.0-alpha6") set(SLIC3R_BUILD_ID "PrusaSlicer-${SLIC3R_VERSION}+UNKNOWN") set(SLIC3R_RC_VERSION "2,6,0,0") set(SLIC3R_RC_VERSION_DOTS "2.6.0.0")