Merge branch 'master' into lm_fdm_custom_supports_polishing

This commit is contained in:
Lukas Matena 2020-05-11 17:03:03 +02:00
commit b046eb4fc9
42 changed files with 919 additions and 1200 deletions

View File

@ -234,7 +234,7 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS})
if (_is_multi) if (_is_multi)
list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE}) list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_RELEASE})
if (MSVC OR OpenVDB_${COMPONENT}_LIBRARY_DEBUG) if (OpenVDB_${COMPONENT}_LIBRARY_DEBUG)
list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG}) list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY_DEBUG})
endif () endif ()

5
deps/CMakeLists.txt vendored
View File

@ -152,6 +152,11 @@ include(MPFR/MPFR.cmake)
include(CGAL/CGAL.cmake) include(CGAL/CGAL.cmake)
include(wxWidgets/wxWidgets.cmake) include(wxWidgets/wxWidgets.cmake)
if (ZLIB_PKG)
add_dependencies(dep_blosc ${ZLIB_PKG})
add_dependencies(dep_openexr ${ZLIB_PKG})
endif ()
if (MSVC) if (MSVC)
add_custom_target(deps ALL add_custom_target(deps ALL

View File

@ -35,8 +35,6 @@ else ()
set(DEP_PLATFORM "x64") set(DEP_PLATFORM "x64")
endif () endif ()
if (${DEP_DEBUG}) if (${DEP_DEBUG})
set(DEP_BOOST_DEBUG "debug") set(DEP_BOOST_DEBUG "debug")
else () else ()
@ -217,7 +215,6 @@ ExternalProject_Add(dep_blosc
#URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9 #URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9
GIT_REPOSITORY https://github.com/Blosc/c-blosc.git GIT_REPOSITORY https://github.com/Blosc/c-blosc.git
GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0 GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0
DEPENDS ${ZLIB_PKG}
CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS CMAKE_ARGS
@ -243,8 +240,7 @@ add_debug_dep(dep_blosc)
ExternalProject_Add(dep_openexr ExternalProject_Add(dep_openexr
EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_ALL 1
GIT_REPOSITORY https://github.com/openexr/openexr.git GIT_REPOSITORY https://github.com/openexr/openexr.git
GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0 GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0
DEPENDS ${ZLIB_PKG}
CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS CMAKE_ARGS

View File

@ -561,10 +561,6 @@ int CLI::run(int argc, char **argv)
gui->mainframe->load_config(m_extra_config); gui->mainframe->load_config(m_extra_config);
}); });
int result = wxEntry(argc, argv); int result = wxEntry(argc, argv);
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
//FIXME this is a workaround for the PrusaSlicer 2.1 release.
_3DScene::destroy();
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
return result; return result;
#else /* SLIC3R_GUI */ #else /* SLIC3R_GUI */
// No GUI support. Just print out a help. // No GUI support. Just print out a help.

View File

@ -107,6 +107,13 @@ namespace ImGui
const char ColorMarkerStart = 0x2; // STX const char ColorMarkerStart = 0x2; // STX
const char ColorMarkerEnd = 0x3; // ETX const char ColorMarkerEnd = 0x3; // ETX
// Special ASCII characters are used here as a ikons markers
const char PrintIconMarker = 0x4;
const char PrinterIconMarker = 0x5;
const char PrinterSlaIconMarker = 0x6;
const char FilamentIconMarker = 0x7;
const char MaterialIconMarker = 0x8;
// void MyFunction(const char* name, const MyMatrix44& v); // void MyFunction(const char* name, const MyMatrix44& v);
} }

View File

@ -1361,7 +1361,6 @@ static void traverse_graph_generate_polylines(
continue; continue;
} }
dont_connect:
// No way to continue the current polyline. Take the rest of the line up to the outer contour. // No way to continue the current polyline. Take the rest of the line up to the outer contour.
// This will finish the polyline, starting another polyline at a new point. // This will finish the polyline, starting another polyline at a new point.
going_up ? ++ it : -- it; going_up ? ++ it : -- it;
@ -1442,6 +1441,8 @@ struct MonotonousRegionLink
AntPath *next_flipped; AntPath *next_flipped;
}; };
// Matrix of paths (AntPath) connecting ends of MontonousRegions.
// AntPath lengths and their derived visibilities refer to the length of the perimeter line if such perimeter segment exists.
class AntPathMatrix class AntPathMatrix
{ {
public: public:
@ -1456,6 +1457,12 @@ public:
// From end of one region to the start of another region, both flipped or not flipped. // From end of one region to the start of another region, both flipped or not flipped.
m_matrix(regions.size() * regions.size() * 4, AntPath{ -1., -1., initial_pheromone}) {} m_matrix(regions.size() * regions.size() * 4, AntPath{ -1., -1., initial_pheromone}) {}
void update_inital_pheromone(float initial_pheromone)
{
for (AntPath &ap : m_matrix)
ap.pheromone = initial_pheromone;
}
AntPath& operator()(const MonotonousRegion &region_from, bool flipped_from, const MonotonousRegion &region_to, bool flipped_to) AntPath& operator()(const MonotonousRegion &region_from, bool flipped_from, const MonotonousRegion &region_to, bool flipped_to)
{ {
int row = 2 * int(&region_from - m_regions.data()) + flipped_from; int row = 2 * int(&region_from - m_regions.data()) + flipped_from;
@ -1478,7 +1485,7 @@ public:
// Just apply the Eucledian distance of the end points. // Just apply the Eucledian distance of the end points.
path.length = unscale<float>(Vec2f(vline_to.pos - vline_from.pos, vline_to.intersections[i_to].pos() - vline_from.intersections[i_from].pos()).norm()); path.length = unscale<float>(Vec2f(vline_to.pos - vline_from.pos, vline_to.intersections[i_to].pos() - vline_from.intersections[i_from].pos()).norm());
} }
path.visibility = 1. / (path.length + EPSILON); path.visibility = 1.f / (path.length + float(EPSILON));
} }
return path; return path;
} }
@ -1497,7 +1504,7 @@ private:
const ExPolygonWithOffset &m_poly_with_offset; const ExPolygonWithOffset &m_poly_with_offset;
const std::vector<SegmentedIntersectionLine> &m_segs; const std::vector<SegmentedIntersectionLine> &m_segs;
// From end of one region to the start of another region, both flipped or not flipped. // From end of one region to the start of another region, both flipped or not flipped.
//FIXME one may possibly use sparse representation of the matrix. //FIXME one may possibly use sparse representation of the matrix, likely using hashing.
std::vector<AntPath> m_matrix; std::vector<AntPath> m_matrix;
}; };
@ -1724,7 +1731,98 @@ static std::vector<MonotonousRegion> generate_montonous_regions(std::vector<Segm
return monotonous_regions; return monotonous_regions;
} }
static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, std::vector<SegmentedIntersectionLine> &segs) // Traverse path, calculate length of the draw for the purpose of optimization.
// This function is very similar to polylines_from_paths() in the way how it traverses the path, but
// polylines_from_paths() emits a path, while this function just calculates the path length.
static float montonous_region_path_length(const MonotonousRegion &region, bool dir, const ExPolygonWithOffset &poly_with_offset, const std::vector<SegmentedIntersectionLine> &segs)
{
// From the initial point (i_vline, i_intersection), follow a path.
int i_intersection = region.left_intersection_point(dir);
int i_vline = region.left.vline;
float total_length = 0.;
bool no_perimeter = false;
Vec2f last_point;
for (;;) {
const SegmentedIntersectionLine &vline = segs[i_vline];
const SegmentIntersection *it = &vline.intersections[i_intersection];
const bool going_up = it->is_low();
if (no_perimeter)
total_length += (last_point - Vec2f(vline.pos, (it + (going_up ? - 1 : 1))->pos())).norm();
int iright = it->right_horizontal();
if (going_up) {
// Traverse the complete vertical segment up to the inner contour.
for (;;) {
do {
++ it;
iright = std::max(iright, it->right_horizontal());
assert(it->is_inner());
} while (it->type != SegmentIntersection::INNER_HIGH || (it + 1)->type != SegmentIntersection::OUTER_HIGH);
int inext = it->vertical_up();
if (inext == -1 || it->vertical_up_quality() != SegmentIntersection::LinkQuality::Valid)
break;
assert(it->iContour == vline.intersections[inext].iContour);
it = vline.intersections.data() + inext;
}
} else {
// Going down.
assert(it->is_high());
assert(i_intersection > 0);
for (;;) {
do {
-- it;
if (int iright_new = it->right_horizontal(); iright_new != -1)
iright = iright_new;
assert(it->is_inner());
} while (it->type != SegmentIntersection::INNER_LOW || (it - 1)->type != SegmentIntersection::OUTER_LOW);
int inext = it->vertical_down();
if (inext == -1 || it->vertical_down_quality() != SegmentIntersection::LinkQuality::Valid)
break;
assert(it->iContour == vline.intersections[inext].iContour);
it = vline.intersections.data() + inext;
}
}
if (i_vline == region.right.vline)
break;
int inext = it->right_horizontal();
if (inext != -1 && it->next_on_contour_quality == SegmentIntersection::LinkQuality::Valid) {
// Summarize length of the connection line along the perimeter.
//FIXME should it be weighted with a lower weight than non-extruding connection line? What weight?
// Taking half of the length.
total_length += 0.5f * float(measure_perimeter_horizontal_segment_length(poly_with_offset, segs, i_vline, it - vline.intersections.data(), inext));
// Don't add distance to the next vertical line start to the total length.
no_perimeter = false;
i_intersection = inext;
} else {
// Finish the current vertical line,
going_up ? ++ it : -- it;
assert(it->is_outer());
assert(it->is_high() == going_up);
// Mark the end of this vertical line.
last_point = Vec2f(vline.pos, it->pos());
// Remember to add distance to the last point.
no_perimeter = true;
if (inext == -1) {
// Find the end of the next overlapping vertical segment.
const SegmentedIntersectionLine &vline_right = segs[i_vline + 1];
const SegmentIntersection *right = going_up ?
&vertical_run_top(vline_right, vline_right.intersections[iright]) : &vertical_run_bottom(vline_right, vline_right.intersections[iright]);
i_intersection = int(right - vline_right.intersections.data());
} else
i_intersection = inext;
}
++ i_vline;
}
return unscale<float>(total_length);
}
static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, const ExPolygonWithOffset &poly_with_offset, std::vector<SegmentedIntersectionLine> &segs)
{ {
// Map from low intersection to left / right side of a monotonous region. // Map from low intersection to left / right side of a monotonous region.
using MapType = std::pair<SegmentIntersection*, MonotonousRegion*>; using MapType = std::pair<SegmentIntersection*, MonotonousRegion*>;
@ -1816,6 +1914,20 @@ static void connect_monotonous_regions(std::vector<MonotonousRegion> &regions, s
} }
} }
#endif /* NDEBUG */ #endif /* NDEBUG */
// Fill in sum length of connecting lines of a region. This length is used for optimizing the infill path for minimum length.
for (MonotonousRegion &region : regions) {
region.len1 = montonous_region_path_length(region, false, poly_with_offset, segs);
region.len2 = montonous_region_path_length(region, true, poly_with_offset, segs);
// Subtract the smaller length from the longer one, so we will optimize just with the positive difference of the two.
if (region.len1 > region.len2) {
region.len1 -= region.len2;
region.len2 = 0;
} else {
region.len2 -= region.len1;
region.len1 = 0;
}
}
} }
// Raad Salman: Algorithms for the Precedence Constrained Generalized Travelling Salesperson Problem // Raad Salman: Algorithms for the Precedence Constrained Generalized Travelling Salesperson Problem
@ -1851,6 +1963,7 @@ inline void print_ant(const std::string& fmt, TArgs&&... args) {
} }
// Find a run through monotonous infill blocks using an 'Ant colony" optimization method. // Find a run through monotonous infill blocks using an 'Ant colony" optimization method.
// http://www.scholarpedia.org/article/Ant_colony_optimization
static std::vector<MonotonousRegionLink> chain_monotonous_regions( static std::vector<MonotonousRegionLink> chain_monotonous_regions(
std::vector<MonotonousRegion> &regions, const ExPolygonWithOffset &poly_with_offset, const std::vector<SegmentedIntersectionLine> &segs, std::mt19937_64 &rng) std::vector<MonotonousRegion> &regions, const ExPolygonWithOffset &poly_with_offset, const std::vector<SegmentedIntersectionLine> &segs, std::mt19937_64 &rng)
{ {
@ -1940,14 +2053,18 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
}; };
#endif /* NDEBUG */ #endif /* NDEBUG */
// How many times to repeat the ant simulation. // How many times to repeat the ant simulation (number of ant generations).
constexpr int num_rounds = 10; constexpr int num_rounds = 25;
// After how many rounds without an improvement to exit?
constexpr int num_rounds_no_change_exit = 8;
// With how many ants each of the run will be performed? // With how many ants each of the run will be performed?
constexpr int num_ants = 10; const int num_ants = std::min<int>(regions.size(), 10);
// Base (initial) pheromone level. // Base (initial) pheromone level. This value will be adjusted based on the length of the first greedy path found.
constexpr float pheromone_initial_deposit = 0.5f; float pheromone_initial_deposit = 0.5f;
// Evaporation rate of pheromones. // Evaporation rate of pheromones.
constexpr float pheromone_evaporation = 0.1f; constexpr float pheromone_evaporation = 0.1f;
// Evaporation rate to diversify paths taken by individual ants.
constexpr float pheromone_diversification = 0.1f;
// Probability at which to take the next best path. Otherwise take the the path based on the cost distribution. // Probability at which to take the next best path. Otherwise take the the path based on the cost distribution.
constexpr float probability_take_best = 0.9f; constexpr float probability_take_best = 0.9f;
// Exponents of the cost function. // Exponents of the cost function.
@ -1956,6 +2073,73 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
AntPathMatrix path_matrix(regions, poly_with_offset, segs, pheromone_initial_deposit); AntPathMatrix path_matrix(regions, poly_with_offset, segs, pheromone_initial_deposit);
// Find an initial path in a greedy way, set the initial pheromone value to 10% of the cost of the greedy path.
{
// Construct the first path in a greedy way to calculate an initial value of the pheromone value.
queue = queue_initial;
left_neighbors_unprocessed = left_neighbors_unprocessed_initial;
assert(validate_unprocessed());
// Pick the last of the queue.
MonotonousRegionLink path_end { queue.back(), false };
queue.pop_back();
-- left_neighbors_unprocessed[path_end.region - regions.data()];
float total_length = path_end.region->length(false);
while (! queue.empty() || ! path_end.region->right_neighbors.empty()) {
// Chain.
MonotonousRegion &region = *path_end.region;
bool dir = path_end.flipped;
NextCandidate next_candidate;
next_candidate.probability = 0;
for (MonotonousRegion *next : region.right_neighbors) {
int &unprocessed = left_neighbors_unprocessed[next - regions.data()];
assert(unprocessed > 1);
if (left_neighbors_unprocessed[next - regions.data()] == 2) {
// Dependencies of the successive blocks are satisfied.
AntPath &path1 = path_matrix(region, dir, *next, false);
AntPath &path2 = path_matrix(region, dir, *next, true);
if (path1.visibility > next_candidate.probability)
next_candidate = { next, &path1, &path1, path1.visibility, false };
if (path2.visibility > next_candidate.probability)
next_candidate = { next, &path2, &path2, path2.visibility, true };
}
}
bool from_queue = next_candidate.probability == 0;
if (from_queue) {
for (MonotonousRegion *next : queue) {
AntPath &path1 = path_matrix(region, dir, *next, false);
AntPath &path2 = path_matrix(region, dir, *next, true);
if (path1.visibility > next_candidate.probability)
next_candidate = { next, &path1, &path1, path1.visibility, false };
if (path2.visibility > next_candidate.probability)
next_candidate = { next, &path2, &path2, path2.visibility, true };
}
}
// Move the other right neighbors with satisified constraints to the queue.
for (MonotonousRegion *next : region.right_neighbors)
if (-- left_neighbors_unprocessed[next - regions.data()] == 1 && next_candidate.region != next)
queue.emplace_back(next);
if (from_queue) {
// Remove the selected path from the queue.
auto it = std::find(queue.begin(), queue.end(), next_candidate.region);
assert(it != queue.end());
*it = queue.back();
queue.pop_back();
}
// Extend the path.
MonotonousRegion *next_region = next_candidate.region;
bool next_dir = next_candidate.dir;
total_length += next_region->length(next_dir) + path_matrix(*path_end.region, path_end.flipped, *next_region, next_dir).length;
path_end = { next_region, next_dir };
assert(left_neighbors_unprocessed[next_region - regions.data()] == 1);
left_neighbors_unprocessed[next_region - regions.data()] = 0;
}
// Set an initial pheromone value to 10% of the greedy path's value.
pheromone_initial_deposit = 0.1 / total_length;
path_matrix.update_inital_pheromone(pheromone_initial_deposit);
}
// Probability (unnormalized) of traversing a link between two monotonous regions. // Probability (unnormalized) of traversing a link between two monotonous regions.
auto path_probability = [pheromone_alpha, pheromone_beta](AntPath &path) { auto path_probability = [pheromone_alpha, pheromone_beta](AntPath &path) {
return pow(path.pheromone, pheromone_alpha) * pow(path.visibility, pheromone_beta); return pow(path.pheromone, pheromone_alpha) * pow(path.visibility, pheromone_beta);
@ -1966,8 +2150,10 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
++ irun; ++ irun;
#endif /* SLIC3R_DEBUG_ANTS */ #endif /* SLIC3R_DEBUG_ANTS */
for (int round = 0; round < num_rounds; ++ round) int num_rounds_no_change = 0;
for (int round = 0; round < num_rounds && num_rounds_no_change < num_rounds_no_change_exit; ++ round)
{ {
bool improved = false;
for (int ant = 0; ant < num_ants; ++ ant) for (int ant = 0; ant < num_ants; ++ ant)
{ {
// Find a new path following the pheromones deposited by the previous ants. // Find a new path following the pheromones deposited by the previous ants.
@ -1977,6 +2163,8 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
left_neighbors_unprocessed = left_neighbors_unprocessed_initial; left_neighbors_unprocessed = left_neighbors_unprocessed_initial;
assert(validate_unprocessed()); assert(validate_unprocessed());
// Pick randomly the first from the queue at random orientation. // Pick randomly the first from the queue at random orientation.
//FIXME picking the 1st monotonous region should likely be done based on accumulated pheromone level as well,
// but the inefficiency caused by the random pick of the 1st monotonous region is likely insignificant.
int first_idx = std::uniform_int_distribution<>(0, int(queue.size()) - 1)(rng); int first_idx = std::uniform_int_distribution<>(0, int(queue.size()) - 1)(rng);
path.emplace_back(MonotonousRegionLink{ queue[first_idx], rng() > rng.max() / 2 }); path.emplace_back(MonotonousRegionLink{ queue[first_idx], rng() > rng.max() / 2 });
*(queue.begin() + first_idx) = std::move(queue.back()); *(queue.begin() + first_idx) = std::move(queue.back());
@ -2051,7 +2239,7 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
for (std::vector<NextCandidate>::iterator it_next_candidate = next_candidates.begin(); it_next_candidate != next_candidates.begin() + num_direct_neighbors; ++ it_next_candidate) for (std::vector<NextCandidate>::iterator it_next_candidate = next_candidates.begin(); it_next_candidate != next_candidates.begin() + num_direct_neighbors; ++ it_next_candidate)
if ((queue.empty() || it_next_candidate->region != queue.back()) && it_next_candidate->region != take_path->region) if ((queue.empty() || it_next_candidate->region != queue.back()) && it_next_candidate->region != take_path->region)
queue.emplace_back(it_next_candidate->region); queue.emplace_back(it_next_candidate->region);
if (take_path - next_candidates.begin() >= num_direct_neighbors) { if (size_t(take_path - next_candidates.begin()) >= num_direct_neighbors) {
// Remove the selected path from the queue. // Remove the selected path from the queue.
auto it = std::find(queue.begin(), queue.end(), take_path->region); auto it = std::find(queue.begin(), queue.end(), take_path->region);
assert(it != queue.end()); assert(it != queue.end());
@ -2083,8 +2271,10 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
path.back().flipped == path.back().region->flips ? path.back().region->right.high : path.back().region->right.low, path.back().flipped == path.back().region->flips ? path.back().region->right.high : path.back().region->right.low,
path.back().flipped == path.back().region->flips ? path.back().region->right.low : path.back().region->right.high); path.back().flipped == path.back().region->flips ? path.back().region->right.low : path.back().region->right.high);
// Update pheromones along this link. // Update pheromones along this link, see Ant Colony System (ACS) update rule.
take_path->link->pheromone = (1.f - pheromone_evaporation) * take_path->link->pheromone + pheromone_evaporation * pheromone_initial_deposit; // http://www.scholarpedia.org/article/Ant_colony_optimization
// The goal here is to lower the pheromone trace for paths taken to diversify the next path picked in the same batch of ants.
take_path->link->pheromone = (1.f - pheromone_diversification) * take_path->link->pheromone + pheromone_diversification * pheromone_initial_deposit;
assert(validate_unprocessed()); assert(validate_unprocessed());
} }
@ -2104,18 +2294,33 @@ static std::vector<MonotonousRegionLink> chain_monotonous_regions(
if (path_length < best_path_length) { if (path_length < best_path_length) {
best_path_length = path_length; best_path_length = path_length;
std::swap(best_path, path); std::swap(best_path, path);
#if 0 // #if ! defined(SLIC3R_DEBUG_ANTS) && ! defined(ndebug)
if (round == 0 && ant == 0)
std::cout << std::endl;
std::cout << Slic3r::format("round %1% ant %2% path length %3%", round, ant, path_length) << std::endl;
#endif
if (path_length == 0)
// Perfect path found.
goto end;
improved = true;
} }
} }
// Reinforce the path feromones with the best path. // Reinforce the path pheromones with the best path.
float total_cost = best_path_length + EPSILON; float total_cost = best_path_length + float(EPSILON);
for (size_t i = 0; i + 1 < path.size(); ++ i) { for (size_t i = 0; i + 1 < path.size(); ++ i) {
MonotonousRegionLink &link = path[i]; MonotonousRegionLink &link = path[i];
link.next->pheromone = (1.f - pheromone_evaporation) * link.next->pheromone + pheromone_evaporation / total_cost; link.next->pheromone = (1.f - pheromone_evaporation) * link.next->pheromone + pheromone_evaporation / total_cost;
} }
if (improved)
num_rounds_no_change = 0;
else
++ num_rounds_no_change;
} }
return best_path; end:
return best_path;
} }
// Traverse path, produce polylines. // Traverse path, produce polylines.
@ -2195,7 +2400,6 @@ static void polylines_from_paths(const std::vector<MonotonousRegionLink> &path,
int inext = it->vertical_up(); int inext = it->vertical_up();
if (inext == -1 || it->vertical_up_quality() != SegmentIntersection::LinkQuality::Valid) if (inext == -1 || it->vertical_up_quality() != SegmentIntersection::LinkQuality::Valid)
break; break;
const Polygon &poly = poly_with_offset.contour(it->iContour);
assert(it->iContour == vline.intersections[inext].iContour); assert(it->iContour == vline.intersections[inext].iContour);
emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_left_vertical_up()); emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_left_vertical_up());
it = vline.intersections.data() + inext; it = vline.intersections.data() + inext;
@ -2215,7 +2419,6 @@ static void polylines_from_paths(const std::vector<MonotonousRegionLink> &path,
int inext = it->vertical_down(); int inext = it->vertical_down();
if (inext == -1 || it->vertical_down_quality() != SegmentIntersection::LinkQuality::Valid) if (inext == -1 || it->vertical_down_quality() != SegmentIntersection::LinkQuality::Valid)
break; break;
const Polygon &poly = poly_with_offset.contour(it->iContour);
assert(it->iContour == vline.intersections[inext].iContour); assert(it->iContour == vline.intersections[inext].iContour);
emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_right_vertical_down()); emit_perimeter_segment_on_vertical_line(poly_with_offset, segs, i_vline, it->iContour, it - vline.intersections.data(), inext, *polyline, it->has_right_vertical_down());
it = vline.intersections.data() + inext; it = vline.intersections.data() + inext;
@ -2285,8 +2488,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
ExPolygonWithOffset poly_with_offset( ExPolygonWithOffset poly_with_offset(
surface->expolygon, surface->expolygon,
- rotate_vector.first, - rotate_vector.first,
scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing), float(scale_(this->overlap - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing)),
scale_(this->overlap - 0.5 * this->spacing)); float(scale_(this->overlap - 0.5 * this->spacing)));
if (poly_with_offset.n_contours_inner == 0) { if (poly_with_offset.n_contours_inner == 0) {
// Not a single infill line fits. // Not a single infill line fits.
//FIXME maybe one shall trigger the gap fill here? //FIXME maybe one shall trigger the gap fill here?
@ -2317,7 +2520,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing; size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
coord_t x0 = bounding_box.min(0); coord_t x0 = bounding_box.min(0);
if (params.full_infill()) if (params.full_infill())
x0 += (line_spacing + SCALED_EPSILON) / 2; x0 += (line_spacing + coord_t(SCALED_EPSILON)) / 2;
#ifdef SLIC3R_DEBUG #ifdef SLIC3R_DEBUG
static int iRun = 0; static int iRun = 0;
@ -2359,7 +2562,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
bool monotonous_infill = params.monotonous; // || params.density > 0.99; bool monotonous_infill = params.monotonous; // || params.density > 0.99;
if (monotonous_infill) { if (monotonous_infill) {
std::vector<MonotonousRegion> regions = generate_montonous_regions(segs); std::vector<MonotonousRegion> regions = generate_montonous_regions(segs);
connect_monotonous_regions(regions, segs); connect_monotonous_regions(regions, poly_with_offset, segs);
if (! regions.empty()) { if (! regions.empty()) {
std::mt19937_64 rng; std::mt19937_64 rng;
std::vector<MonotonousRegionLink> path = chain_monotonous_regions(regions, poly_with_offset, segs, rng); std::vector<MonotonousRegionLink> path = chain_monotonous_regions(regions, poly_with_offset, segs, rng);
@ -2478,10 +2681,10 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams &para
params3.dont_connect = true; params3.dont_connect = true;
Polylines polylines_out; Polylines polylines_out;
coordf_t dx = sqrt(0.5) * z; coordf_t dx = sqrt(0.5) * z;
if (! fill_surface_by_lines(surface, params2, 0.f, dx, polylines_out) || if (! fill_surface_by_lines(surface, params2, 0.f, float(dx), polylines_out) ||
! fill_surface_by_lines(surface, params2, float(M_PI / 3.), - dx, polylines_out) || ! fill_surface_by_lines(surface, params2, float(M_PI / 3.), - float(dx), polylines_out) ||
// Rotated by PI*2/3 + PI to achieve reverse sloping wall. // Rotated by PI*2/3 + PI to achieve reverse sloping wall.
! fill_surface_by_lines(surface, params3, float(M_PI * 2. / 3.), dx, polylines_out)) { ! fill_surface_by_lines(surface, params3, float(M_PI * 2. / 3.), float(dx), polylines_out)) {
printf("FillCubic::fill_surface() failed to fill a region.\n"); printf("FillCubic::fill_surface() failed to fill a region.\n");
} }
return polylines_out; return polylines_out;

View File

@ -117,7 +117,8 @@ const Color GCodePreviewData::Extrusion::Default_Extrusion_Role_Colors[erCount]
Color(1.0f, 1.0f, 0.0f, 1.0f), // erInternalInfill Color(1.0f, 1.0f, 0.0f, 1.0f), // erInternalInfill
Color(1.0f, 0.0f, 1.0f, 1.0f), // erSolidInfill Color(1.0f, 0.0f, 1.0f, 1.0f), // erSolidInfill
Color(0.0f, 1.0f, 1.0f, 1.0f), // erTopSolidInfill Color(0.0f, 1.0f, 1.0f, 1.0f), // erTopSolidInfill
Color(0.0f, 1.0f, 1.0f, 1.0f), // erIroning // Color(1.0f, 0.7f, 0.61f, 1.0f), // erIroning
Color(1.0f, 0.55f, 0.41f, 1.0f), // erIroning
Color(0.5f, 0.5f, 0.5f, 1.0f), // erBridgeInfill Color(0.5f, 0.5f, 0.5f, 1.0f), // erBridgeInfill
Color(1.0f, 1.0f, 1.0f, 1.0f), // erGapFill Color(1.0f, 1.0f, 1.0f, 1.0f), // erGapFill
Color(0.5f, 0.0f, 0.0f, 1.0f), // erSkirt Color(0.5f, 0.0f, 0.0f, 1.0f), // erSkirt

View File

@ -1292,7 +1292,7 @@ void SupportTreeBuildsteps::routing_headless()
m_thr(); m_thr();
const auto R = double(m_support_pts[i].head_front_radius); const auto R = double(m_support_pts[i].head_front_radius);
const double HWIDTH_MM = m_cfg.head_penetration_mm; const double HWIDTH_MM = std::min(R, m_cfg.head_penetration_mm);
// Exact support position // Exact support position
Vec3d sph = m_support_pts[i].pos.cast<double>(); Vec3d sph = m_support_pts[i].pos.cast<double>();

View File

@ -53,8 +53,5 @@
// Enable rendering of objects colored by facets' slope // Enable rendering of objects colored by facets' slope
#define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_3_0_ALPHA1) #define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_3_0_ALPHA1)
// Moves GLCanvas3DManager from being a static member of _3DScene to be a normal member of GUI_App
#define ENABLE_NON_STATIC_CANVAS_MANAGER (1 && ENABLE_2_3_0_ALPHA1)
#endif // _prusaslicer_technologies_h_ #endif // _prusaslicer_technologies_h_

View File

@ -27,8 +27,8 @@ set(SLIC3R_GUI_SOURCES
GUI/GLShader.hpp GUI/GLShader.hpp
GUI/GLCanvas3D.hpp GUI/GLCanvas3D.hpp
GUI/GLCanvas3D.cpp GUI/GLCanvas3D.cpp
GUI/GLCanvas3DManager.hpp GUI/OpenGLManager.hpp
GUI/GLCanvas3DManager.cpp GUI/OpenGLManager.cpp
GUI/Selection.hpp GUI/Selection.hpp
GUI/Selection.cpp GUI/Selection.cpp
GUI/Gizmos/GLGizmosManager.cpp GUI/Gizmos/GLGizmosManager.cpp
@ -216,6 +216,12 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES}) target_link_libraries(libslic3r_gui ${DBUS_LIBRARIES})
endif() endif()
if (SLIC3R_STATIC)
# FIXME: This was previously exported by wx-config but the wxWidgets
# cmake build forgets this and the build fails in debug mode (or on raspberry release)
target_compile_definitions(libslic3r_gui PUBLIC -DwxDEBUG_LEVEL=0)
endif()
if(APPLE) if(APPLE)
target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY}) target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY})
endif() endif()

View File

@ -410,7 +410,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
if (boost::algorithm::iends_with(m_texture_filename, ".svg")) if (boost::algorithm::iends_with(m_texture_filename, ".svg"))
{ {
// use higher resolution images if graphic card and opengl version allow // use higher resolution images if graphic card and opengl version allow
GLint max_tex_size = GLCanvas3DManager::get_gl_info().get_max_tex_size(); GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename)) if ((m_temp_texture.get_id() == 0) || (m_temp_texture.get_source() != m_texture_filename))
{ {
// generate a temporary lower resolution texture to show while no main texture levels have been compressed // generate a temporary lower resolution texture to show while no main texture levels have been compressed

View File

@ -1854,10 +1854,6 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height
thick_point_to_verts(point, width, height, volume); thick_point_to_verts(point, width, height, volume);
} }
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
GUI::GLCanvas3DManager _3DScene::s_canvas_mgr;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
GLModel::GLModel() GLModel::GLModel()
: m_filename("") : m_filename("")
{ {
@ -2148,41 +2144,4 @@ bool GLBed::on_init_from_file(const std::string& filename)
return true; return true;
} }
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
std::string _3DScene::get_gl_info(bool format_as_html, bool extensions)
{
return Slic3r::GUI::GLCanvas3DManager::get_gl_info().to_string(format_as_html, extensions);
}
bool _3DScene::add_canvas(wxGLCanvas* canvas, GUI::Bed3D& bed, GUI::Camera& camera, GUI::GLToolbar& view_toolbar)
{
return s_canvas_mgr.add(canvas, bed, camera, view_toolbar);
}
bool _3DScene::remove_canvas(wxGLCanvas* canvas)
{
return s_canvas_mgr.remove(canvas);
}
void _3DScene::remove_all_canvases()
{
s_canvas_mgr.remove_all();
}
bool _3DScene::init(wxGLCanvas* canvas)
{
return s_canvas_mgr.init(canvas);
}
void _3DScene::destroy()
{
s_canvas_mgr.destroy();
}
GUI::GLCanvas3D* _3DScene::get_canvas(wxGLCanvas* canvas)
{
return s_canvas_mgr.get_canvas(canvas);
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
} // namespace Slic3r } // namespace Slic3r

View File

@ -7,9 +7,6 @@
#include "libslic3r/TriangleMesh.hpp" #include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Utils.hpp" #include "libslic3r/Utils.hpp"
#include "libslic3r/Model.hpp" #include "libslic3r/Model.hpp"
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
#include "slic3r/GUI/GLCanvas3DManager.hpp"
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#include <functional> #include <functional>
@ -668,30 +665,8 @@ protected:
bool on_init_from_file(const std::string& filename) override; bool on_init_from_file(const std::string& filename) override;
}; };
#if ENABLE_NON_STATIC_CANVAS_MANAGER
struct _3DScene struct _3DScene
#else
class _3DScene
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
static GUI::GLCanvas3DManager s_canvas_mgr;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
public:
static std::string get_gl_info(bool format_as_html, bool extensions);
static bool add_canvas(wxGLCanvas* canvas, GUI::Bed3D& bed, GUI::Camera& camera, GUI::GLToolbar& view_toolbar);
static bool remove_canvas(wxGLCanvas* canvas);
static void remove_all_canvases();
static bool init(wxGLCanvas* canvas);
static void destroy();
static GUI::GLCanvas3D* get_canvas(wxGLCanvas* canvas);
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume); static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume); static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
static void extrusionentity_to_verts(const Polyline &polyline, float width, float height, float print_z, GLVolume& volume); static void extrusionentity_to_verts(const Polyline &polyline, float width, float height, float print_z, GLVolume& volume);

View File

@ -19,9 +19,7 @@
#include "slic3r/GUI/PresetBundle.hpp" #include "slic3r/GUI/PresetBundle.hpp"
#include "slic3r/GUI/Tab.hpp" #include "slic3r/GUI/Tab.hpp"
#include "slic3r/GUI/GUI_Preview.hpp" #include "slic3r/GUI/GUI_Preview.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER #include "slic3r/GUI/OpenGLManager.hpp"
#include "slic3r/GUI/GLCanvas3DManager.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include "slic3r/GUI/3DBed.hpp" #include "slic3r/GUI/3DBed.hpp"
#include "slic3r/GUI/Camera.hpp" #include "slic3r/GUI/Camera.hpp"
@ -360,13 +358,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
const Size& cnv_size = canvas.get_canvas_size(); const Size& cnv_size = canvas.get_canvas_size();
float half_w = 0.5f * (float)cnv_size.get_width(); float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height(); float half_h = 0.5f * (float)cnv_size.get_height();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
} }
@ -864,11 +856,7 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0)) if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
{ {
const Size& cnv_size = canvas.get_canvas_size(); const Size& cnv_size = canvas.get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float left = (-0.5f * (float)m_original_width) * inv_zoom; float left = (-0.5f * (float)m_original_width) * inv_zoom;
float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom; float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
float right = left + (float)m_original_width * inv_zoom; float right = left + (float)m_original_width * inv_zoom;
@ -1235,11 +1223,7 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0)) if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
{ {
const Size& cnv_size = canvas.get_canvas_size(); const Size& cnv_size = canvas.get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom; float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
float right = left + (float)m_original_width * inv_zoom; float right = left + (float)m_original_width * inv_zoom;
@ -1265,11 +1249,7 @@ void GLCanvas3D::Labels::render(const std::vector<const ModelInstance*>& sorted_
if (!m_enabled || !is_shown()) if (!m_enabled || !is_shown())
return; return;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
#else
const Camera& camera = m_canvas.get_camera();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const Model* model = m_canvas.get_model(); const Model* model = m_canvas.get_model();
if (model == nullptr) if (model == nullptr)
return; return;
@ -1551,22 +1531,13 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RELOAD_FROM_DISK, SimpleEvent);
const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25; const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
#else
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
: m_canvas(canvas) : m_canvas(canvas)
, m_context(nullptr) , m_context(nullptr)
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
, m_retina_helper(nullptr) , m_retina_helper(nullptr)
#endif #endif
, m_in_render(false) , m_in_render(false)
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
, m_bed(bed)
, m_camera(camera)
, m_view_toolbar(view_toolbar)
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
, m_main_toolbar(GLToolbar::Normal, "Top") , m_main_toolbar(GLToolbar::Normal, "Top")
, m_undoredo_toolbar(GLToolbar::Normal, "Top") , m_undoredo_toolbar(GLToolbar::Normal, "Top")
, m_collapse_toolbar(GLToolbar::Normal, "Top") , m_collapse_toolbar(GLToolbar::Normal, "Top")
@ -1603,10 +1574,6 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
m_timer.SetOwner(m_canvas); m_timer.SetOwner(m_canvas);
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
m_retina_helper.reset(new RetinaHelper(canvas)); m_retina_helper.reset(new RetinaHelper(canvas));
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
m_view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size);
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#endif // ENABLE_RETINA_GL #endif // ENABLE_RETINA_GL
} }
@ -1720,7 +1687,6 @@ void GLCanvas3D::reset_volumes()
if (!m_initialized) if (!m_initialized)
return; return;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_volumes.empty()) if (m_volumes.empty())
return; return;
@ -1731,18 +1697,6 @@ void GLCanvas3D::reset_volumes()
m_dirty = true; m_dirty = true;
_set_warning_texture(WarningTexture::ObjectOutside, false); _set_warning_texture(WarningTexture::ObjectOutside, false);
#else
_set_current();
if (!m_volumes.empty())
{
m_selection.clear();
m_volumes.clear();
m_dirty = true;
}
_set_warning_texture(WarningTexture::ObjectOutside, false);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
int GLCanvas3D::check_volumes_outside_state() const int GLCanvas3D::check_volumes_outside_state() const
@ -1831,11 +1785,7 @@ void GLCanvas3D::set_model(Model* model)
void GLCanvas3D::bed_shape_changed() void GLCanvas3D::bed_shape_changed()
{ {
refresh_camera_scene_box(); refresh_camera_scene_box();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().requires_zoom_to_bed = true; wxGetApp().plater()->get_camera().requires_zoom_to_bed = true;
#else
m_camera.requires_zoom_to_bed = true;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty = true; m_dirty = true;
} }
@ -1844,12 +1794,10 @@ void GLCanvas3D::set_color_by(const std::string& value)
m_color_by = value; m_color_by = value;
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void GLCanvas3D::refresh_camera_scene_box() void GLCanvas3D::refresh_camera_scene_box()
{ {
wxGetApp().plater()->get_camera().set_scene_box(scene_bounding_box()); wxGetApp().plater()->get_camera().set_scene_box(scene_bounding_box());
} }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
{ {
@ -1865,12 +1813,7 @@ BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
BoundingBoxf3 GLCanvas3D::scene_bounding_box() const BoundingBoxf3 GLCanvas3D::scene_bounding_box() const
{ {
BoundingBoxf3 bb = volumes_bounding_box(); BoundingBoxf3 bb = volumes_bounding_box();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(true)); bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(true));
#else
bb.merge(m_bed.get_bounding_box(true));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_config != nullptr) if (m_config != nullptr)
{ {
double h = m_config->opt_float("max_print_height"); double h = m_config->opt_float("max_print_height");
@ -1992,11 +1935,7 @@ void GLCanvas3D::allow_multisample(bool allow)
void GLCanvas3D::zoom_to_bed() void GLCanvas3D::zoom_to_bed()
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
_zoom_to_box(wxGetApp().plater()->get_bed().get_bounding_box(false)); _zoom_to_box(wxGetApp().plater()->get_bed().get_bounding_box(false));
#else
_zoom_to_box(m_bed.get_bounding_box(false));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
void GLCanvas3D::zoom_to_volumes() void GLCanvas3D::zoom_to_volumes()
@ -2014,11 +1953,7 @@ void GLCanvas3D::zoom_to_selection()
void GLCanvas3D::select_view(const std::string& direction) void GLCanvas3D::select_view(const std::string& direction)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().select_view(direction); wxGetApp().plater()->get_camera().select_view(direction);
#else
m_camera.select_view(direction);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_canvas != nullptr) if (m_canvas != nullptr)
m_canvas->Refresh(); m_canvas->Refresh();
} }
@ -2046,26 +1981,17 @@ void GLCanvas3D::render()
return; return;
// ensures this canvas is current and initialized // ensures this canvas is current and initialized
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (!_is_shown_on_screen() || !_set_current() || !wxGetApp().init_opengl()) if (!_is_shown_on_screen() || !_set_current() || !wxGetApp().init_opengl())
return; return;
if (!is_initialized() && !init()) if (!is_initialized() && !init())
return; return;
#else
if (! _is_shown_on_screen() || !_set_current() || !_3DScene::init(m_canvas))
return;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_RENDER_STATISTICS #if ENABLE_RENDER_STATISTICS
auto start_time = std::chrono::high_resolution_clock::now(); auto start_time = std::chrono::high_resolution_clock::now();
#endif // ENABLE_RENDER_STATISTICS #endif // ENABLE_RENDER_STATISTICS
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (wxGetApp().plater()->get_bed().get_shape().empty()) if (wxGetApp().plater()->get_bed().get_shape().empty())
#else
if (m_bed.get_shape().empty())
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
// this happens at startup when no data is still saved under <>\AppData\Roaming\Slic3rPE // this happens at startup when no data is still saved under <>\AppData\Roaming\Slic3rPE
post_event(SimpleEvent(EVT_GLCANVAS_UPDATE_BED_SHAPE)); post_event(SimpleEvent(EVT_GLCANVAS_UPDATE_BED_SHAPE));
@ -2077,7 +2003,6 @@ void GLCanvas3D::render()
// to preview, this was called before canvas had its final size. It reported zero width // to preview, this was called before canvas had its final size. It reported zero width
// and the viewport was set incorrectly, leading to tripping glAsserts further down // and the viewport was set incorrectly, leading to tripping glAsserts further down
// the road (in apply_projection). That's why the minimum size is forced to 10. // the road (in apply_projection). That's why the minimum size is forced to 10.
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Camera& camera = wxGetApp().plater()->get_camera(); Camera& camera = wxGetApp().plater()->get_camera();
camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height())); camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
@ -2090,19 +2015,6 @@ void GLCanvas3D::render()
camera.apply_view_matrix(); camera.apply_view_matrix();
camera.apply_projection(_max_bounding_box(true, true)); camera.apply_projection(_max_bounding_box(true, true));
#else
m_camera.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
if (m_camera.requires_zoom_to_bed)
{
zoom_to_bed();
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
m_camera.requires_zoom_to_bed = false;
}
m_camera.apply_view_matrix();
m_camera.apply_projection(_max_bounding_box(true, true));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f }; GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam)); glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
@ -2132,11 +2044,7 @@ void GLCanvas3D::render()
_render_objects(); _render_objects();
_render_sla_slices(); _render_sla_slices();
_render_selection(); _render_selection();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
_render_bed(!camera.is_looking_downward(), true); _render_bed(!camera.is_looking_downward(), true);
#else
_render_bed(!m_camera.is_looking_downward(), true);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_RENDER_SELECTION_CENTER #if ENABLE_RENDER_SELECTION_CENTER
_render_selection_center(); _render_selection_center();
@ -2174,10 +2082,10 @@ void GLCanvas3D::render()
ImGui::Separator(); ImGui::Separator();
imgui.text("Compressed textures: "); imgui.text("Compressed textures: ");
ImGui::SameLine(); ImGui::SameLine();
imgui.text(GLCanvas3DManager::are_compressed_textures_supported() ? "supported" : "not supported"); imgui.text(OpenGLManager::are_compressed_textures_supported() ? "supported" : "not supported");
imgui.text("Max texture size: "); imgui.text("Max texture size: ");
ImGui::SameLine(); ImGui::SameLine();
imgui.text(std::to_string(GLCanvas3DManager::get_gl_info().get_max_tex_size())); imgui.text(std::to_string(OpenGLManager::get_gl_info().get_max_tex_size()));
imgui.end(); imgui.end();
#endif // ENABLE_RENDER_STATISTICS #endif // ENABLE_RENDER_STATISTICS
@ -2208,16 +2116,13 @@ void GLCanvas3D::render()
tooltip = m_collapse_toolbar.get_tooltip(); tooltip = m_collapse_toolbar.get_tooltip();
if (tooltip.empty()) if (tooltip.empty())
#if ENABLE_NON_STATIC_CANVAS_MANAGER
tooltip = wxGetApp().plater()->get_view_toolbar().get_tooltip(); tooltip = wxGetApp().plater()->get_view_toolbar().get_tooltip();
#else
tooltip = m_view_toolbar.get_tooltip();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
set_tooltip(tooltip); set_tooltip(tooltip);
m_tooltip.render(m_mouse.position, *this); if (m_tooltip_enabled)
m_tooltip.render(m_mouse.position, *this);
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI #endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog(*this); wxGetApp().plater()->get_mouse3d_controller().render_settings_dialog(*this);
@ -2258,15 +2163,10 @@ void GLCanvas3D::render()
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const
{ {
switch (GLCanvas3DManager::get_framebuffers_type()) switch (OpenGLManager::get_framebuffers_type())
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER case OpenGLManager::EFramebufferType::Arb: { _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
case GLCanvas3DManager::EFramebufferType::Arb: { _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; } case OpenGLManager::EFramebufferType::Ext: { _render_thumbnail_framebuffer_ext(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
case GLCanvas3DManager::EFramebufferType::Ext: { _render_thumbnail_framebuffer_ext(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
#else
case GLCanvas3DManager::FB_Arb: { _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
case GLCanvas3DManager::FB_Ext: { _render_thumbnail_framebuffer_ext(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
default: { _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; } default: { _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, show_bed, transparent_background); break; }
} }
} }
@ -2371,15 +2271,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr)) if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
return; return;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (!m_initialized) if (!m_initialized)
return; return;
_set_current(); _set_current();
#else
if (m_initialized)
_set_current();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
struct ModelVolumeState { struct ModelVolumeState {
ModelVolumeState(const GLVolume* volume) : ModelVolumeState(const GLVolume* volume) :
@ -2933,6 +2828,9 @@ void GLCanvas3D::bind_event_handlers()
m_canvas->Bind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Bind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this);
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
} }
} }
@ -2960,6 +2858,9 @@ void GLCanvas3D::unbind_event_handlers()
m_canvas->Unbind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Unbind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this);
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
} }
} }
@ -2976,13 +2877,8 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
m_dirty |= m_main_toolbar.update_items_state(); m_dirty |= m_main_toolbar.update_items_state();
m_dirty |= m_undoredo_toolbar.update_items_state(); m_dirty |= m_undoredo_toolbar.update_items_state();
m_dirty |= m_collapse_toolbar.update_items_state(); m_dirty |= m_collapse_toolbar.update_items_state();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state(); m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state();
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera()); bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera());
#else
m_dirty |= m_view_toolbar.update_items_state();
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(m_camera);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty |= mouse3d_controller_applied; m_dirty |= mouse3d_controller_applied;
if (!m_dirty) if (!m_dirty)
@ -3146,11 +3042,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'I': case 'I':
case 'i': { _update_camera_zoom(1.0); break; } case 'i': { _update_camera_zoom(1.0); break; }
case 'K': case 'K':
#if ENABLE_NON_STATIC_CANVAS_MANAGER
case 'k': { wxGetApp().plater()->get_camera().select_next_type(); m_dirty = true; break; } case 'k': { wxGetApp().plater()->get_camera().select_next_type(); m_dirty = true; break; }
#else
case 'k': { m_camera.select_next_type(); m_dirty = true; break; }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
case 'O': case 'O':
case 'o': { _update_camera_zoom(-1.0); break; } case 'o': { _update_camera_zoom(-1.0); break; }
#if ENABLE_RENDER_PICKING_PASS #if ENABLE_RENDER_PICKING_PASS
@ -3277,11 +3169,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
Vec3d displacement; Vec3d displacement;
if (camera_space) if (camera_space)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> inv_view_3x3 = wxGetApp().plater()->get_camera().get_view_matrix().inverse().matrix().block(0, 0, 3, 3); Eigen::Matrix<double, 3, 3, Eigen::DontAlign> inv_view_3x3 = wxGetApp().plater()->get_camera().get_view_matrix().inverse().matrix().block(0, 0, 3, 3);
#else
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> inv_view_3x3 = m_camera.get_view_matrix().inverse().matrix().block(0, 0, 3, 3);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
displacement = multiplier * (inv_view_3x3 * direction); displacement = multiplier * (inv_view_3x3 * direction);
displacement(2) = 0.0; displacement(2) = 0.0;
} }
@ -3624,11 +3512,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
return; return;
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this)) if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this))
#else
if (m_view_toolbar.on_mouse(evt, *this))
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
mouse_up_cleanup(); mouse_up_cleanup();
@ -3676,12 +3560,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (top_level_wnd && top_level_wnd->IsActive()) if (top_level_wnd && top_level_wnd->IsActive())
m_canvas->SetFocus(); m_canvas->SetFocus();
m_mouse.position = pos.cast<double>(); m_mouse.position = pos.cast<double>();
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
m_tooltip_enabled = false;
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
// 1) forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while // 1) forces a frame render to ensure that m_hover_volume_idxs is updated even when the user right clicks while
// the context menu is shown, ensuring it to disappear if the mouse is outside any volume and to // the context menu is shown, ensuring it to disappear if the mouse is outside any volume and to
// change the volume hover state if any is under the mouse // change the volume hover state if any is under the mouse
// 2) when switching between 3d view and preview the size of the canvas changes if the side panels are visible, // 2) when switching between 3d view and preview the size of the canvas changes if the side panels are visible,
// so forces a resize to avoid multiple renders with different sizes (seen as flickering) // so forces a resize to avoid multiple renders with different sizes (seen as flickering)
_refresh_if_shown_on_screen(); _refresh_if_shown_on_screen();
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
m_tooltip_enabled = true;
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
} }
m_mouse.set_start_position_2D_as_invalid(); m_mouse.set_start_position_2D_as_invalid();
//#endif //#endif
@ -3689,7 +3579,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
else if (evt.Leaving()) else if (evt.Leaving())
{ {
_deactivate_undo_redo_toolbar_items(); _deactivate_undo_redo_toolbar_items();
_deactivate_search_toolbar_item();
// to remove hover on objects when the mouse goes out of this canvas // to remove hover on objects when the mouse goes out of this canvas
m_mouse.position = Vec2d(-1.0, -1.0); m_mouse.position = Vec2d(-1.0, -1.0);
@ -3793,12 +3682,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag // we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag
if (m_selection.contains_volume(get_first_hover_volume_idx())) if (m_selection.contains_volume(get_first_hover_volume_idx()))
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
if (std::abs(camera.get_dir_forward()(2)) < EPSILON) if (std::abs(camera.get_dir_forward()(2)) < EPSILON)
#else
if (std::abs(m_camera.get_dir_forward()(2)) < EPSILON)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
// side view -> move selected volumes orthogonally to camera view direction // side view -> move selected volumes orthogonally to camera view direction
Linef3 ray = mouse_ray(pos); Linef3 ray = mouse_ray(pos);
@ -3811,13 +3696,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// vector from the starting position to the found intersection // vector from the starting position to the found intersection
Vec3d inters_vec = inters - m_mouse.drag.start_position_3D; Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Vec3d camera_right = camera.get_dir_right(); Vec3d camera_right = camera.get_dir_right();
Vec3d camera_up = camera.get_dir_up(); Vec3d camera_up = camera.get_dir_up();
#else
Vec3d camera_right = m_camera.get_dir_right();
Vec3d camera_up = m_camera.get_dir_up();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// finds projection of the vector along the camera axes // finds projection of the vector along the camera axes
double projection_x = inters_vec.dot(camera_right); double projection_x = inters_vec.dot(camera_right);
@ -3867,25 +3747,16 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.); const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.);
if (wxGetApp().app_config->get("use_free_camera") == "1") if (wxGetApp().app_config->get("use_free_camera") == "1")
// Virtual track ball (similar to the 3DConnexion mouse). // Virtual track ball (similar to the 3DConnexion mouse).
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.)); wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
#else
m_camera.rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
else else
{ {
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation. // Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
// It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(), // It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(),
// which checks an atomics (flushes CPU caches). // which checks an atomics (flushes CPU caches).
// See GH issue #3816. // See GH issue #3816.
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Camera& camera = wxGetApp().plater()->get_camera(); Camera& camera = wxGetApp().plater()->get_camera();
camera.recover_from_free_camera(); camera.recover_from_free_camera();
camera.rotate_on_sphere(rot.x(), rot.y(), wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA); camera.rotate_on_sphere(rot.x(), rot.y(), wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA);
#else
m_camera.recover_from_free_camera();
m_camera.rotate_on_sphere(rot.x(), rot.y(), wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
m_dirty = true; m_dirty = true;
@ -3901,23 +3772,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
float z = 0.0f; float z = 0.0f;
const Vec3d& cur_pos = _mouse_to_3d(pos, &z); const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z); Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Camera& camera = wxGetApp().plater()->get_camera(); Camera& camera = wxGetApp().plater()->get_camera();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (wxGetApp().app_config->get("use_free_camera") != "1") if (wxGetApp().app_config->get("use_free_camera") != "1")
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation. // Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
// It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(), // It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(),
// which checks an atomics (flushes CPU caches). // which checks an atomics (flushes CPU caches).
// See GH issue #3816. // See GH issue #3816.
#if ENABLE_NON_STATIC_CANVAS_MANAGER
camera.recover_from_free_camera(); camera.recover_from_free_camera();
camera.set_target(camera.get_target() + orig - cur_pos); camera.set_target(camera.get_target() + orig - cur_pos);
#else
m_camera.recover_from_free_camera();
m_camera.set_target(m_camera.get_target() + orig - cur_pos);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty = true; m_dirty = true;
} }
@ -4022,6 +3885,15 @@ void GLCanvas3D::on_paint(wxPaintEvent& evt)
this->render(); this->render();
} }
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
void GLCanvas3D::on_set_focus(wxFocusEvent& evt)
{
m_tooltip_enabled = false;
_refresh_if_shown_on_screen();
m_tooltip_enabled = true;
}
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
Size GLCanvas3D::get_canvas_size() const Size GLCanvas3D::get_canvas_size() const
{ {
int w = 0; int w = 0;
@ -4366,15 +4238,14 @@ void GLCanvas3D::update_ui_from_settings()
if (new_scaling != orig_scaling) { if (new_scaling != orig_scaling) {
BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling; BOOST_LOG_TRIVIAL(debug) << "GLCanvas3D: Scaling factor: " << new_scaling;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Camera& camera = wxGetApp().plater()->get_camera(); Camera& camera = wxGetApp().plater()->get_camera();
camera.set_zoom(camera.get_zoom() * new_scaling / orig_scaling); camera.set_zoom(camera.get_zoom() * new_scaling / orig_scaling);
#else
m_camera.set_zoom(m_camera.get_zoom() * new_scaling / orig_scaling);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
_refresh_if_shown_on_screen(); _refresh_if_shown_on_screen();
} }
#endif #endif // ENABLE_RETINA_GL
bool enable_collapse = wxGetApp().app_config->get("show_collapse_button") == "1";
enable_collapse_toolbar(enable_collapse);
} }
@ -4406,11 +4277,7 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const double GLCanvas3D::get_size_proportional_to_max_bed_size(double factor) const
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
return factor * wxGetApp().plater()->get_bed().get_bounding_box(false).max_size(); return factor * wxGetApp().plater()->get_bed().get_bounding_box(false).max_size();
#else
return factor * m_bed.get_bounding_box(false).max_size();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
void GLCanvas3D::set_cursor(ECursorType type) void GLCanvas3D::set_cursor(ECursorType type)
@ -4432,6 +4299,16 @@ void GLCanvas3D::msw_rescale()
m_warning_texture.msw_rescale(*this); m_warning_texture.msw_rescale(*this);
} }
void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar()
{
std::string new_tooltip = _u8L("Switch to Settings") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
m_main_toolbar.set_tooltip(get_main_toolbar_item_id("settings"), new_tooltip);
}
bool GLCanvas3D::has_toolpaths_to_export() const bool GLCanvas3D::has_toolpaths_to_export() const
{ {
return m_volumes.has_toolpaths_to_export(); return m_volumes.has_toolpaths_to_export();
@ -4473,11 +4350,7 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) const
ImGuiWrapper* imgui = wxGetApp().imgui(); ImGuiWrapper* imgui = wxGetApp().imgui();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
#else
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
imgui->set_next_window_pos(x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); imgui->set_next_window_pos(x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
std::string title = is_undo ? L("Undo History") : L("Redo History"); std::string title = is_undo ? L("Undo History") : L("Redo History");
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
@ -4518,22 +4391,17 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
bool action_taken = false; bool action_taken = false;
ImGuiWrapper* imgui = wxGetApp().imgui(); ImGuiWrapper* imgui = wxGetApp().imgui();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
#else
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
#endif
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f); imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
std::string title = L("Search"); std::string title = L("Search");
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
int selected = -1; int selected = -1;
bool edited = false; bool edited = false;
bool check_changed = false;
float em = static_cast<float>(wxGetApp().em_unit()); float em = static_cast<float>(wxGetApp().em_unit());
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
em *= m_retina_helper->get_scale_factor(); em *= m_retina_helper->get_scale_factor();
#endif #endif // ENABLE_RETINA_GL
Sidebar& sidebar = wxGetApp().sidebar(); Sidebar& sidebar = wxGetApp().sidebar();
@ -4543,7 +4411,7 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s, imgui->search_list(ImVec2(45 * em, 30 * em), &search_string_getter, s,
sidebar.get_searcher().view_params, sidebar.get_searcher().view_params,
selected, edited, m_mouse_wheel); selected, edited, m_mouse_wheel, wxGetApp().is_localized());
search_line = s; search_line = s;
delete [] s; delete [] s;
@ -4553,11 +4421,12 @@ bool GLCanvas3D::_render_search_list(float pos_x) const
if (edited) if (edited)
sidebar.search(); sidebar.search();
if (selected != size_t(-1)) { if (selected >= 0) {
// selected == 9999 means that Esc kye was pressed // selected == 9999 means that Esc kye was pressed
if (selected != 9999) if (selected == 9999)
action_taken = true;
else
sidebar.jump_to_option(selected); sidebar.jump_to_option(selected);
action_taken = true;
} }
imgui->end(); imgui->end();
@ -4635,11 +4504,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, bool
// extends the near and far z of the frustrum to avoid the bed being clipped // extends the near and far z of the frustrum to avoid the bed being clipped
// box in eye space // box in eye space
#if ENABLE_NON_STATIC_CANVAS_MANAGER
BoundingBoxf3 t_bed_box = wxGetApp().plater()->get_bed().get_bounding_box(true).transformed(camera.get_view_matrix()); BoundingBoxf3 t_bed_box = wxGetApp().plater()->get_bed().get_bounding_box(true).transformed(camera.get_view_matrix());
#else
BoundingBoxf3 t_bed_box = m_bed.get_bounding_box(true).transformed(camera.get_view_matrix());
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
near_z = -t_bed_box.max(2); near_z = -t_bed_box.max(2);
far_z = -t_bed_box.min(2); far_z = -t_bed_box.min(2);
} }
@ -4916,11 +4781,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT
// restore the default framebuffer size to avoid flickering on the 3D scene // restore the default framebuffer size to avoid flickering on the 3D scene
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); wxGetApp().plater()->get_camera().apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height());
#else
m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height());
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
bool GLCanvas3D::_init_toolbars() bool GLCanvas3D::_init_toolbars()
@ -5075,10 +4936,26 @@ bool GLCanvas3D::_init_main_toolbar()
if (!m_main_toolbar.add_separator()) if (!m_main_toolbar.add_separator())
return false; return false;
item.name = "settings";
item.icon_filename = "cog.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ;
item.sprite_id = 10;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
item.visibility_callback = [this]() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" ||
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); };
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(); };
if (!m_main_toolbar.add_item(item))
return false;
if (!m_main_toolbar.add_separator())
return false;
item.name = "layersediting"; item.name = "layersediting";
item.icon_filename = "layers_white.svg"; item.icon_filename = "layers_white.svg";
item.tooltip = _utf8(L("Variable layer height")); item.tooltip = _utf8(L("Variable layer height"));
item.sprite_id = 10; item.sprite_id = 11;
item.left.toggable = true; item.left.toggable = true;
item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); }; item.left.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool item.visibility_callback = [this]()->bool
@ -5100,7 +4977,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "search"; item.name = "search";
item.icon_filename = "search_.svg"; item.icon_filename = "search_.svg";
item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]"; item.tooltip = _utf8(L("Search")) + " [" + GUI::shortkey_ctrl_prefix() + "F]";
item.sprite_id = 11; item.sprite_id = 12;
item.left.render_callback = [this](float left, float right, float, float) { item.left.render_callback = [this](float left, float right, float, float) {
if (m_canvas != nullptr) if (m_canvas != nullptr)
{ {
@ -5236,7 +5113,7 @@ bool GLCanvas3D::_init_view_toolbar()
bool GLCanvas3D::_init_collapse_toolbar() bool GLCanvas3D::_init_collapse_toolbar()
{ {
if (!m_collapse_toolbar.is_enabled()) if (!m_collapse_toolbar.is_enabled() && m_collapse_toolbar.get_items_count() > 0)
return true; return true;
BackgroundTexture::Metadata background_data; BackgroundTexture::Metadata background_data;
@ -5277,61 +5154,10 @@ bool GLCanvas3D::_init_collapse_toolbar()
wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed()); wxGetApp().plater()->collapse_sidebar(!wxGetApp().plater()->is_sidebar_collapsed());
}; };
if (!m_collapse_toolbar.add_item(item))
return false;
if (!m_collapse_toolbar.add_separator())
return false;
item.name = "print";
item.icon_filename = "cog.svg";
item.tooltip = _utf8(L("Switch to Print Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "2]";
item.sprite_id = 1;
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*0*/1); };
if (!m_collapse_toolbar.add_item(item))
return false;
item.name = "filament";
item.icon_filename = "spool.svg";
item.tooltip = _utf8(L("Switch to Filament Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
item.sprite_id = 2;
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
item.visibility_callback = [this]() { return wxGetApp().plater()->printer_technology() == ptFFF; };
if (!m_collapse_toolbar.add_item(item))
return false;
item.name = "printer";
item.icon_filename = "printer.svg";
item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
item.sprite_id = 3;
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
if (!m_collapse_toolbar.add_item(item))
return false;
item.name = "resin";
item.icon_filename = "resin.svg";
item.tooltip = _utf8(L("Switch to SLA Material Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
item.sprite_id = 4;
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*1*/2); };
item.visibility_callback = [this]() { return m_process->current_printer_technology() == ptSLA; };
if (!m_collapse_toolbar.add_item(item))
return false;
item.name = "sla_printer";
item.icon_filename = "sla_printer.svg";
item.tooltip = _utf8(L("Switch to Printer Settings")) + " [" + GUI::shortkey_ctrl_prefix() + "4]";
item.sprite_id = 5;
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(/*2*/3); };
if (!m_collapse_toolbar.add_item(item)) if (!m_collapse_toolbar.add_item(item))
return false; return false;
return true; return true;
} }
bool GLCanvas3D::_set_current() bool GLCanvas3D::_set_current()
@ -5371,31 +5197,19 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be
bb.merge(BoundingBoxf3(sel_bb_center - extend_by, sel_bb_center + extend_by)); bb.merge(BoundingBoxf3(sel_bb_center - extend_by, sel_bb_center + extend_by));
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(include_bed_model)); bb.merge(wxGetApp().plater()->get_bed().get_bounding_box(include_bed_model));
#else
bb.merge(m_bed.get_bounding_box(include_bed_model));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
return bb; return bb;
} }
void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor) void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().zoom_to_box(box, margin_factor); wxGetApp().plater()->get_camera().zoom_to_box(box, margin_factor);
#else
m_camera.zoom_to_box(box, margin_factor);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty = true; m_dirty = true;
} }
void GLCanvas3D::_update_camera_zoom(double zoom) void GLCanvas3D::_update_camera_zoom(double zoom)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_camera().update_zoom(zoom); wxGetApp().plater()->get_camera().update_zoom(zoom);
#else
m_camera.update_zoom(zoom);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_dirty = true; m_dirty = true;
} }
@ -5591,11 +5405,7 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes) const
(m_gizmos.get_current_type() != GLGizmosManager::FdmSupports (m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
&& m_gizmos.get_current_type() != GLGizmosManager::SlaSupports); && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports);
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGetApp().plater()->get_bed().render(const_cast<GLCanvas3D&>(*this), bottom, scale_factor, show_axes, show_texture); wxGetApp().plater()->get_bed().render(const_cast<GLCanvas3D&>(*this), bottom, scale_factor, show_axes, show_texture);
#else
m_bed.render(const_cast<GLCanvas3D&>(*this), theta, scale_factor, show_axes);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
void GLCanvas3D::_render_objects() const void GLCanvas3D::_render_objects() const
@ -5614,11 +5424,7 @@ void GLCanvas3D::_render_objects() const
if (m_config != nullptr) if (m_config != nullptr)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false); const BoundingBoxf3& bed_bb = wxGetApp().plater()->get_bed().get_bounding_box(false);
#else
const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height")); m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
m_volumes.check_outside_state(m_config, nullptr); m_volumes.check_outside_state(m_config, nullptr);
} }
@ -5634,37 +5440,20 @@ void GLCanvas3D::_render_objects() const
m_shader.start_using(); m_shader.start_using();
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) { if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
int object_id = m_layers_editing.last_object_id; int object_id = m_layers_editing.last_object_id;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) { m_volumes.render(GLVolumeCollection::Opaque, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
// Which volume to paint without the layer height profile shader? // Which volume to paint without the layer height profile shader?
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id); return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
}); });
#else
m_volumes.render(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume& volume) {
// Which volume to paint without the layer height profile shader?
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
});
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// Let LayersEditing handle rendering of the active object using the layer height profile shader. // Let LayersEditing handle rendering of the active object using the layer height profile shader.
m_layers_editing.render_volumes(*this, this->m_volumes); m_layers_editing.render_volumes(*this, this->m_volumes);
} else { } else {
// do not cull backfaces to show broken geometry, if any // do not cull backfaces to show broken geometry, if any
#if ENABLE_NON_STATIC_CANVAS_MANAGER
m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) { m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
}); });
#else
m_volumes.render(GLVolumeCollection::Opaque, m_picking_enabled, m_camera.get_view_matrix(), [this](const GLVolume& volume) {
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
});
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix()); m_volumes.render(GLVolumeCollection::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
#else
m_volumes.render(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_shader.stop_using(); m_shader.stop_using();
m_camera_clipping_plane = ClippingPlane::ClipsNothing(); m_camera_clipping_plane = ClippingPlane::ClipsNothing();
@ -5675,7 +5464,7 @@ void GLCanvas3D::_render_selection() const
float scale_factor = 1.0; float scale_factor = 1.0;
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
scale_factor = m_retina_helper->get_scale_factor(); scale_factor = m_retina_helper->get_scale_factor();
#endif #endif // ENABLE_RETINA_GL
if (!m_gizmos.is_running()) if (!m_gizmos.is_running())
m_selection.render(scale_factor); m_selection.render(scale_factor);
@ -5694,16 +5483,10 @@ void GLCanvas3D::_render_overlays() const
glsafe(::glPushMatrix()); glsafe(::glPushMatrix());
glsafe(::glLoadIdentity()); glsafe(::glLoadIdentity());
// ensure that the textures are renderered inside the frustrum // ensure that the textures are renderered inside the frustrum
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.005))); glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.005)));
// ensure that the overlay fits the frustrum near z plane // ensure that the overlay fits the frustrum near z plane
double gui_scale = camera.get_gui_scale(); double gui_scale = camera.get_gui_scale();
#else
glsafe(::glTranslated(0.0, 0.0, -(m_camera.get_near_z() + 0.005)));
// ensure that the overlay fits the frustrum near z plane
double gui_scale = m_camera.get_gui_scale();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
glsafe(::glScaled(gui_scale, gui_scale, 1.0)); glsafe(::glScaled(gui_scale, gui_scale, 1.0));
_render_gizmos_overlay(); _render_gizmos_overlay();
@ -5773,11 +5556,7 @@ void GLCanvas3D::_render_volumes_for_picking() const
glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix(); const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
#else
const Transform3d& view_matrix = m_camera.get_view_matrix();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
for (size_t type = 0; type < 2; ++ type) { for (size_t type = 0; type < 2; ++ type) {
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::Opaque : GLVolumeCollection::Transparent, view_matrix); GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::Opaque : GLVolumeCollection::Transparent, view_matrix);
for (const GLVolumeWithIdAndZ& volume : to_render) for (const GLVolumeWithIdAndZ& volume : to_render)
@ -5826,11 +5605,7 @@ void GLCanvas3D::_render_main_toolbar() const
return; return;
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)m_camera.get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width()) * inv_zoom; float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width()) * inv_zoom;
@ -5845,11 +5620,7 @@ void GLCanvas3D::_render_undoredo_toolbar() const
return; return;
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)m_camera.get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width())) * inv_zoom; float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width())) * inv_zoom;
@ -5863,11 +5634,7 @@ void GLCanvas3D::_render_collapse_toolbar() const
return; return;
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)m_camera.get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0; float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0;
@ -5880,50 +5647,27 @@ void GLCanvas3D::_render_collapse_toolbar() const
void GLCanvas3D::_render_view_toolbar() const void GLCanvas3D::_render_view_toolbar() const
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar(); GLToolbar& view_toolbar = wxGetApp().plater()->get_view_toolbar();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
// m_view_toolbar.set_scale(m_retina_helper->get_scale_factor()); // m_view_toolbar.set_scale(m_retina_helper->get_scale_factor());
const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale(); const float scale = m_retina_helper->get_scale_factor() * wxGetApp().toolbar_icon_scale();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
view_toolbar.set_scale(scale); //! #ys_FIXME_experiment view_toolbar.set_scale(scale); //! #ys_FIXME_experiment
#else
m_view_toolbar.set_scale(scale); //! #ys_FIXME_experiment
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#else #else
// m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor()); // m_view_toolbar.set_scale(m_canvas->GetContentScaleFactor());
// m_view_toolbar.set_scale(wxGetApp().em_unit()*0.1f); // m_view_toolbar.set_scale(wxGetApp().em_unit()*0.1f);
const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale()); const float size = int(GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale());
#if ENABLE_NON_STATIC_CANVAS_MANAGER
view_toolbar.set_icons_size(size); //! #ys_FIXME_experiment view_toolbar.set_icons_size(size); //! #ys_FIXME_experiment
#else
m_view_toolbar.set_icons_size(size); //! #ys_FIXME_experiment
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#endif // ENABLE_RETINA_GL #endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size(); Size cnv_size = get_canvas_size();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)m_camera.get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// places the toolbar on the bottom-left corner of the 3d scene // places the toolbar on the bottom-left corner of the 3d scene
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float top = (-0.5f * (float)cnv_size.get_height() + view_toolbar.get_height()) * inv_zoom; float top = (-0.5f * (float)cnv_size.get_height() + view_toolbar.get_height()) * inv_zoom;
#else
float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom; float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
view_toolbar.set_position(top, left); view_toolbar.set_position(top, left);
view_toolbar.render(*this); view_toolbar.render(*this);
#else
m_view_toolbar.set_position(top, left);
m_view_toolbar.render(*this);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
#if ENABLE_SHOW_CAMERA_TARGET #if ENABLE_SHOW_CAMERA_TARGET
@ -6202,16 +5946,10 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z)
if (m_canvas == nullptr) if (m_canvas == nullptr)
return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX); return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX);
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
const std::array<int, 4>& viewport = camera.get_viewport(); const std::array<int, 4>& viewport = camera.get_viewport();
const Transform3d& modelview_matrix = camera.get_view_matrix(); const Transform3d& modelview_matrix = camera.get_view_matrix();
const Transform3d& projection_matrix = camera.get_projection_matrix(); const Transform3d& projection_matrix = camera.get_projection_matrix();
#else
const std::array<int, 4>& viewport = m_camera.get_viewport();
const Transform3d& modelview_matrix = m_camera.get_view_matrix();
const Transform3d& projection_matrix = m_camera.get_projection_matrix();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
GLint y = viewport[3] - (GLint)mouse_pos(1); GLint y = viewport[3] - (GLint)mouse_pos(1);
GLfloat mouse_z; GLfloat mouse_z;

View File

@ -16,9 +16,6 @@
#include "GUI_ObjectLayers.hpp" #include "GUI_ObjectLayers.hpp"
#include "GLSelectionRectangle.hpp" #include "GLSelectionRectangle.hpp"
#include "MeshUtils.hpp" #include "MeshUtils.hpp"
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
#include "Camera.hpp"
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#include <float.h> #include <float.h>
@ -31,9 +28,7 @@ class wxMouseEvent;
class wxTimerEvent; class wxTimerEvent;
class wxPaintEvent; class wxPaintEvent;
class wxGLCanvas; class wxGLCanvas;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
class wxGLContext; class wxGLContext;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// Support for Retina OpenGL on Mac OS // Support for Retina OpenGL on Mac OS
#define ENABLE_RETINA_GL __APPLE__ #define ENABLE_RETINA_GL __APPLE__
@ -451,11 +446,6 @@ private:
LegendTexture m_legend_texture; LegendTexture m_legend_texture;
WarningTexture m_warning_texture; WarningTexture m_warning_texture;
wxTimer m_timer; wxTimer m_timer;
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
Bed3D& m_bed;
Camera& m_camera;
GLToolbar& m_view_toolbar;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
LayersEditing m_layers_editing; LayersEditing m_layers_editing;
Shader m_shader; Shader m_shader;
Mouse m_mouse; Mouse m_mouse;
@ -518,22 +508,17 @@ private:
Labels m_labels; Labels m_labels;
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI #if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
mutable Tooltip m_tooltip; mutable Tooltip m_tooltip;
mutable bool m_tooltip_enabled{ true };
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI #endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
#if ENABLE_SLOPE_RENDERING #if ENABLE_SLOPE_RENDERING
Slope m_slope; Slope m_slope;
#endif // ENABLE_SLOPE_RENDERING #endif // ENABLE_SLOPE_RENDERING
public: public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
explicit GLCanvas3D(wxGLCanvas* canvas); explicit GLCanvas3D(wxGLCanvas* canvas);
#else
GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
~GLCanvas3D(); ~GLCanvas3D();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool is_initialized() const { return m_initialized; } bool is_initialized() const { return m_initialized; }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
void set_context(wxGLContext* context) { m_context = context; } void set_context(wxGLContext* context) { m_context = context; }
@ -581,13 +566,7 @@ public:
void set_color_by(const std::string& value); void set_color_by(const std::string& value);
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void refresh_camera_scene_box(); void refresh_camera_scene_box();
#else
void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); }
const Camera& get_camera() const { return m_camera; }
Camera& get_camera() { return m_camera; }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const Shader& get_shader() const { return m_shader; } const Shader& get_shader() const { return m_shader; }
BoundingBoxf3 volumes_bounding_box() const; BoundingBoxf3 volumes_bounding_box() const;
@ -661,6 +640,9 @@ public:
void on_timer(wxTimerEvent& evt); void on_timer(wxTimerEvent& evt);
void on_mouse(wxMouseEvent& evt); void on_mouse(wxMouseEvent& evt);
void on_paint(wxPaintEvent& evt); void on_paint(wxPaintEvent& evt);
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
void on_set_focus(wxFocusEvent& evt);
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
Size get_canvas_size() const; Size get_canvas_size() const;
Vec2d get_local_mouse_position() const; Vec2d get_local_mouse_position() const;
@ -684,10 +666,6 @@ public:
void update_ui_from_settings(); void update_ui_from_settings();
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
float get_view_toolbar_height() const { return m_view_toolbar.get_height(); }
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; }
int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); } int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); }
void set_selected_extruder(int extruder) { m_selected_extruder = extruder;} void set_selected_extruder(int extruder) { m_selected_extruder = extruder;}
@ -730,6 +708,7 @@ public:
int get_main_toolbar_item_id(const std::string& name) const { return m_main_toolbar.get_item_id(name); } int get_main_toolbar_item_id(const std::string& name) const { return m_main_toolbar.get_item_id(name); }
void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); } void force_main_toolbar_left_action(int item_id) { m_main_toolbar.force_left_action(item_id, *this); }
void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); } void force_main_toolbar_right_action(int item_id) { m_main_toolbar.force_right_action(item_id, *this); }
void update_tooltip_for_settings_item_in_main_toolbar();
bool has_toolpaths_to_export() const; bool has_toolpaths_to_export() const;
void export_toolpaths_to_obj(const char* filename) const; void export_toolpaths_to_obj(const char* filename) const;

View File

@ -1,211 +0,0 @@
#ifndef slic3r_GLCanvas3DManager_hpp_
#define slic3r_GLCanvas3DManager_hpp_
#include "libslic3r/BoundingBox.hpp"
#include <map>
#include <vector>
class wxWindow;
class wxGLCanvas;
class wxGLContext;
namespace Slic3r {
class BackgroundSlicingProcess;
class DynamicPrintConfig;
class Model;
class ExPolygon;
typedef std::vector<ExPolygon> ExPolygons;
class ModelObject;
class PrintObject;
namespace GUI {
class GLCanvas3D;
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
class Bed3D;
class GLToolbar;
struct Camera;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
class GLCanvas3DManager
{
public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
enum class EFramebufferType : unsigned char
{
Unknown,
Arb,
Ext
};
#else
enum EFramebufferType : unsigned char
{
FB_None,
FB_Arb,
FB_Ext
};
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
class GLInfo
{
#if ENABLE_NON_STATIC_CANVAS_MANAGER
mutable bool m_detected{ false };
mutable int m_max_tex_size{ 0 };
mutable float m_max_anisotropy{ 0.0f };
mutable std::string m_version;
mutable std::string m_glsl_version;
mutable std::string m_vendor;
mutable std::string m_renderer;
#else
mutable bool m_detected;
mutable std::string m_version;
mutable std::string m_glsl_version;
mutable std::string m_vendor;
mutable std::string m_renderer;
mutable int m_max_tex_size;
mutable float m_max_anisotropy;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
GLInfo() = default;
#else
GLInfo();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const std::string& get_version() const;
const std::string& get_glsl_version() const;
const std::string& get_vendor() const;
const std::string& get_renderer() const;
int get_max_tex_size() const;
float get_max_anisotropy() const;
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
std::string to_string(bool format_as_html, bool extensions) const;
private:
void detect() const;
};
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
struct OSInfo
{
int major{ 0 };
int minor{ 0 };
int micro{ 0 };
};
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
private:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
enum class EMultisampleState : unsigned char
{
Unknown,
Enabled,
Disabled
};
#else
enum EMultisampleState : unsigned char
{
MS_Unknown,
MS_Enabled,
MS_Disabled
};
typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool m_gl_initialized{ false };
wxGLContext* m_context{ nullptr };
#else
wxGLContext* m_context;
bool m_gl_initialized;
CanvasesMap m_canvases;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
static GLInfo s_gl_info;
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
static OSInfo s_os_info;
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
static bool s_compressed_textures_supported;
static EMultisampleState s_multisample;
static EFramebufferType s_framebuffers_type;
public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
GLCanvas3DManager() = default;
#else
GLCanvas3DManager();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
~GLCanvas3DManager();
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
bool add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
bool remove(wxGLCanvas* canvas);
void remove_all();
size_t count() const;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool init_gl();
#else
void init_gl();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGLContext* init_glcontext(wxGLCanvas& canvas);
#else
bool init(wxGLCanvas* canvas);
void destroy();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
GLCanvas3D* get_canvas(wxGLCanvas* canvas);
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; }
static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }
#else
static bool can_multisample() { return s_multisample == MS_Enabled; }
static bool are_framebuffers_supported() { return (s_framebuffers_type != FB_None); }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
static wxGLCanvas* create_wxglcanvas(wxWindow& parent);
#else
static wxGLCanvas* create_wxglcanvas(wxWindow *parent);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
static const GLInfo& get_gl_info() { return s_gl_info; }
private:
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
CanvasesMap::iterator do_get_canvas(wxGLCanvas* canvas);
CanvasesMap::const_iterator do_get_canvas(wxGLCanvas* canvas) const;
bool init(GLCanvas3D& canvas);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
static void detect_multisample(int* attribList);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLCanvas3DManager_hpp_

View File

@ -2,9 +2,7 @@
#include "Camera.hpp" #include "Camera.hpp"
#include "3DScene.hpp" #include "3DScene.hpp"
#include "GLCanvas3D.hpp" #include "GLCanvas3D.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#include "GUI_App.hpp" #include "GUI_App.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <GL/glew.h> #include <GL/glew.h>
@ -38,11 +36,7 @@ namespace GUI {
m_state = Off; m_state = Off;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
#else
const Camera& camera = canvas.get_camera();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const std::array<int, 4>& viewport = camera.get_viewport(); const std::array<int, 4>& viewport = camera.get_viewport();
const Transform3d& modelview_matrix = camera.get_view_matrix(); const Transform3d& modelview_matrix = camera.get_view_matrix();
const Transform3d& projection_matrix = camera.get_projection_matrix(); const Transform3d& projection_matrix = camera.get_projection_matrix();
@ -75,11 +69,7 @@ namespace GUI {
if (!is_dragging()) if (!is_dragging())
return; return;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
#else
const Camera& camera = canvas.get_camera();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)camera.get_inv_zoom(); float inv_zoom = (float)camera.get_inv_zoom();
Size cnv_size = canvas.get_canvas_size(); Size cnv_size = canvas.get_canvas_size();

View File

@ -2,9 +2,7 @@
#include "GLTexture.hpp" #include "GLTexture.hpp"
#include "3DScene.hpp" #include "3DScene.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER #include "OpenGLManager.hpp"
#include "GLCanvas3DManager.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <GL/glew.h> #include <GL/glew.h>
@ -443,7 +441,7 @@ bool GLTexture::load_from_png(const std::string& filename, bool use_mipmaps, ECo
if (apply_anisotropy) if (apply_anisotropy)
{ {
GLfloat max_anisotropy = GLCanvas3DManager::get_gl_info().get_max_anisotropy(); GLfloat max_anisotropy = OpenGLManager::get_gl_info().get_max_anisotropy();
if (max_anisotropy > 1.0f) if (max_anisotropy > 1.0f)
glsafe(::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy)); glsafe(::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy));
} }
@ -592,7 +590,7 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, boo
if (apply_anisotropy) if (apply_anisotropy)
{ {
GLfloat max_anisotropy = GLCanvas3DManager::get_gl_info().get_max_anisotropy(); GLfloat max_anisotropy = OpenGLManager::get_gl_info().get_max_anisotropy();
if (max_anisotropy > 1.0f) if (max_anisotropy > 1.0f)
glsafe(::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy)); glsafe(::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy));
} }

View File

@ -3,14 +3,9 @@
#include "GLToolbar.hpp" #include "GLToolbar.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/Camera.hpp" #include "slic3r/GUI/Camera.hpp"
#else
#include "../../slic3r/GUI/GLCanvas3D.hpp"
#include "../../slic3r/GUI/Camera.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <wx/event.h> #include <wx/event.h>
#include <wx/bitmap.h> #include <wx/bitmap.h>
@ -252,7 +247,7 @@ bool GLToolbar::is_enabled() const
void GLToolbar::set_enabled(bool enable) void GLToolbar::set_enabled(bool enable)
{ {
m_enabled = true; m_enabled = enable;//true; etFIXME
} }
bool GLToolbar::add_item(const GLToolbarItem::Data& data) bool GLToolbar::add_item(const GLToolbarItem::Data& data)
@ -729,11 +724,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
{ {
// NB: mouse_pos is already scaled appropriately // NB: mouse_pos is already scaled appropriately
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = m_layout.scale * inv_zoom; float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size(); Size cnv_size = parent.get_canvas_size();
@ -874,11 +865,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
{ {
// NB: mouse_pos is already scaled appropriately // NB: mouse_pos is already scaled appropriately
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = m_layout.scale * inv_zoom; float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size(); Size cnv_size = parent.get_canvas_size();
@ -1027,11 +1014,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
{ {
// NB: mouse_pos is already scaled appropriately // NB: mouse_pos is already scaled appropriately
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = m_layout.scale * inv_zoom; float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size(); Size cnv_size = parent.get_canvas_size();
@ -1104,11 +1087,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
{ {
// NB: mouse_pos is already scaled appropriately // NB: mouse_pos is already scaled appropriately
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = m_layout.scale * inv_zoom; float factor = m_layout.scale * inv_zoom;
Size cnv_size = parent.get_canvas_size(); Size cnv_size = parent.get_canvas_size();
@ -1260,11 +1239,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
int tex_width = m_icons_texture.get_width(); int tex_width = m_icons_texture.get_width();
int tex_height = m_icons_texture.get_height(); int tex_height = m_icons_texture.get_height();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = inv_zoom * m_layout.scale; float factor = inv_zoom * m_layout.scale;
float scaled_icons_size = m_layout.icons_size * factor; float scaled_icons_size = m_layout.icons_size * factor;
@ -1312,11 +1287,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
int tex_width = m_icons_texture.get_width(); int tex_width = m_icons_texture.get_width();
int tex_height = m_icons_texture.get_height(); int tex_height = m_icons_texture.get_height();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float factor = inv_zoom * m_layout.scale; float factor = inv_zoom * m_layout.scale;
float scaled_icons_size = m_layout.icons_size * factor; float scaled_icons_size = m_layout.icons_size * factor;

View File

@ -283,22 +283,20 @@ GUI_App::~GUI_App()
delete preset_updater; delete preset_updater;
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
std::string GUI_App::get_gl_info(bool format_as_html, bool extensions) std::string GUI_App::get_gl_info(bool format_as_html, bool extensions)
{ {
return GLCanvas3DManager::get_gl_info().to_string(format_as_html, extensions); return OpenGLManager::get_gl_info().to_string(format_as_html, extensions);
} }
wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas) wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas)
{ {
return m_canvas_mgr.init_glcontext(canvas); return m_opengl_mgr.init_glcontext(canvas);
} }
bool GUI_App::init_opengl() bool GUI_App::init_opengl()
{ {
return m_canvas_mgr.init_gl(); return m_opengl_mgr.init_gl();
} }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
void GUI_App::init_app_config() void GUI_App::init_app_config()
{ {
@ -324,6 +322,7 @@ void GUI_App::init_app_config()
app_config->load(); app_config->load();
} }
} }
bool GUI_App::OnInit() bool GUI_App::OnInit()
{ {
try { try {
@ -413,7 +412,8 @@ bool GUI_App::on_init_inner()
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr) if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
wxImage::AddHandler(new wxPNGHandler()); wxImage::AddHandler(new wxPNGHandler());
mainframe = new MainFrame(); mainframe = new MainFrame();
mainframe->switch_to(true); // hide settings tabs after first Layout // hide settings tabs after first Layout
mainframe->select_tab(0);
sidebar().obj_list()->init_objects(); // propagate model objects to object list sidebar().obj_list()->init_objects(); // propagate model objects to object list
// update_mode(); // !!! do that later // update_mode(); // !!! do that later
@ -591,17 +591,18 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const
return 0.01f * int_val * icon_sc; return 0.01f * int_val * icon_sc;
} }
void GUI_App::recreate_GUI() void GUI_App::recreate_GUI(const wxString& msg_name)
{ {
mainframe->shutdown(); mainframe->shutdown();
const auto msg_name = _(L("Changing of an application language")) + dots;
wxProgressDialog dlg(msg_name, msg_name); wxProgressDialog dlg(msg_name, msg_name);
dlg.Pulse(); dlg.Pulse();
dlg.Update(10, _(L("Recreating")) + dots); dlg.Update(10, _(L("Recreating")) + dots);
MainFrame *old_main_frame = mainframe; MainFrame *old_main_frame = mainframe;
mainframe = new MainFrame(); mainframe = new MainFrame();
// hide settings tabs after first Layout
mainframe->select_tab(0);
// Propagate model objects to object list. // Propagate model objects to object list.
sidebar().obj_list()->init_objects(); sidebar().obj_list()->init_objects();
SetTopWindow(mainframe); SetTopWindow(mainframe);
@ -705,12 +706,6 @@ void GUI_App::load_project(wxWindow *parent, wxString& input_file) const
void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
{ {
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
if (this->plater_ != nullptr)
// hides the tooltip
plater_->get_current_canvas3D()->set_tooltip("");
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
input_files.Clear(); input_files.Clear();
wxFileDialog dialog(parent ? parent : GetTopWindow(), wxFileDialog dialog(parent ? parent : GetTopWindow(),
_(L("Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):")), _(L("Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):")),
@ -724,7 +719,7 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
bool GUI_App::switch_language() bool GUI_App::switch_language()
{ {
if (select_language()) { if (select_language()) {
recreate_GUI(); recreate_GUI(_L("Changing of an application language") + dots);
return true; return true;
} else { } else {
return false; return false;
@ -1028,8 +1023,17 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
break; break;
case ConfigMenuPreferences: case ConfigMenuPreferences:
{ {
PreferencesDialog dlg(mainframe); bool recreate_app = false;
dlg.ShowModal(); {
// the dialog needs to be destroyed before the call to recreate_GUI()
// or sometimes the application crashes into wxDialogBase() destructor
// so we put it into an inner scope
PreferencesDialog dlg(mainframe);
dlg.ShowModal();
recreate_app = dlg.settings_layout_changed();
}
if (recreate_app)
recreate_GUI(_L("Changing of the settings layout") + dots);
break; break;
} }
case ConfigMenuLanguage: case ConfigMenuLanguage:

View File

@ -7,9 +7,7 @@
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "ImGuiWrapper.hpp" #include "ImGuiWrapper.hpp"
#include "ConfigWizard.hpp" #include "ConfigWizard.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER #include "OpenGLManager.hpp"
#include "GLCanvas3DManager.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <wx/app.h> #include <wx/app.h>
#include <wx/colour.h> #include <wx/colour.h>
@ -100,9 +98,7 @@ class GUI_App : public wxApp
// Best translation language, provided by Windows or OSX, owned by wxWidgets. // Best translation language, provided by Windows or OSX, owned by wxWidgets.
const wxLanguageInfo *m_language_info_best = nullptr; const wxLanguageInfo *m_language_info_best = nullptr;
#if ENABLE_NON_STATIC_CANVAS_MANAGER OpenGLManager m_opengl_mgr;
GLCanvas3DManager m_canvas_mgr;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager; std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
@ -117,11 +113,9 @@ public:
GUI_App(); GUI_App();
~GUI_App() override; ~GUI_App() override;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
static std::string get_gl_info(bool format_as_html, bool extensions); static std::string get_gl_info(bool format_as_html, bool extensions);
wxGLContext* init_glcontext(wxGLCanvas& canvas); wxGLContext* init_glcontext(wxGLCanvas& canvas);
bool init_opengl(); bool init_opengl();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
static unsigned get_colour_approx_luma(const wxColour &colour); static unsigned get_colour_approx_luma(const wxColour &colour);
static bool dark_mode(); static bool dark_mode();
@ -142,7 +136,7 @@ public:
int em_unit() const { return m_em_unit; } int em_unit() const { return m_em_unit; }
float toolbar_icon_scale(const bool is_limited = false) const; float toolbar_icon_scale(const bool is_limited = false) const;
void recreate_GUI(); void recreate_GUI(const wxString& message);
void system_info(); void system_info();
void keyboard_shortcuts(); void keyboard_shortcuts();
void load_project(wxWindow *parent, wxString& input_file) const; void load_project(wxWindow *parent, wxString& input_file) const;
@ -168,6 +162,7 @@ public:
wxString current_language_code() const { return m_wxLocale->GetCanonicalName(); } wxString current_language_code() const { return m_wxLocale->GetCanonicalName(); }
// Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US". // Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US".
wxString current_language_code_safe() const; wxString current_language_code_safe() const;
bool is_localized() const { return m_wxLocale->GetLocale() != "English"; }
virtual bool OnExceptionInMainLoop() override; virtual bool OnExceptionInMainLoop() override;

View File

@ -7,7 +7,7 @@
#include "AppConfig.hpp" #include "AppConfig.hpp"
#include "3DScene.hpp" #include "3DScene.hpp"
#include "BackgroundSlicingProcess.hpp" #include "BackgroundSlicingProcess.hpp"
#include "GLCanvas3DManager.hpp" #include "OpenGLManager.hpp"
#include "GLCanvas3D.hpp" #include "GLCanvas3D.hpp"
#include "PresetBundle.hpp" #include "PresetBundle.hpp"
#include "DoubleSlider.hpp" #include "DoubleSlider.hpp"
@ -27,65 +27,36 @@
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
: m_canvas_widget(nullptr) : m_canvas_widget(nullptr)
, m_canvas(nullptr) , m_canvas(nullptr)
{ {
init(parent, model, config, process); init(parent, model, config, process);
} }
#else
View3D::View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
: m_canvas_widget(nullptr)
, m_canvas(nullptr)
{
init(parent, bed, camera, view_toolbar, model, config, process);
}
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
View3D::~View3D() View3D::~View3D()
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_canvas != nullptr) if (m_canvas != nullptr)
delete m_canvas; delete m_canvas;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_canvas_widget != nullptr) if (m_canvas_widget != nullptr)
{
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
_3DScene::remove_canvas(m_canvas_widget);
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
delete m_canvas_widget; delete m_canvas_widget;
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
m_canvas = nullptr;
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
}
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
#else
bool View3D::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false; return false;
#if ENABLE_NON_STATIC_CANVAS_MANAGER m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(*this);
if (m_canvas_widget == nullptr) if (m_canvas_widget == nullptr)
return false; return false;
m_canvas = new GLCanvas3D(m_canvas_widget); m_canvas = new GLCanvas3D(m_canvas_widget);
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget)); m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
m_canvas->bind_event_handlers(); m_canvas->bind_event_handlers();
#else
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_canvas->allow_multisample(GLCanvas3DManager::can_multisample()); m_canvas->allow_multisample(OpenGLManager::can_multisample());
// XXX: If have OpenGL // XXX: If have OpenGL
m_canvas->enable_picking(true); m_canvas->enable_picking(true);
m_canvas->enable_moving(true); m_canvas->enable_moving(true);
@ -199,15 +170,9 @@ void View3D::render()
m_canvas->set_as_dirty(); m_canvas->set_as_dirty();
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Preview::Preview( Preview::Preview(
wxWindow* parent, Model* model, DynamicPrintConfig* config, wxWindow* parent, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func) BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
#else
Preview::Preview(
wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
: m_canvas_widget(nullptr) : m_canvas_widget(nullptr)
, m_canvas(nullptr) , m_canvas(nullptr)
, m_double_slider_sizer(nullptr) , m_double_slider_sizer(nullptr)
@ -232,40 +197,26 @@ Preview::Preview(
, m_volumes_cleanup_required(false) , m_volumes_cleanup_required(false)
#endif // __linux__ #endif // __linux__
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (init(parent, model)) if (init(parent, model))
#else
if (init(parent, bed, camera, view_toolbar, model))
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
show_hide_ui_elements("none"); show_hide_ui_elements("none");
load_print(); load_print();
} }
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool Preview::init(wxWindow* parent, Model* model) bool Preview::init(wxWindow* parent, Model* model)
#else
bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false; return false;
#if ENABLE_NON_STATIC_CANVAS_MANAGER m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(*this);
if (m_canvas_widget == nullptr) if (m_canvas_widget == nullptr)
return false; return false;
m_canvas = new GLCanvas3D(m_canvas_widget); m_canvas = new GLCanvas3D(m_canvas_widget);
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget)); m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
m_canvas->bind_event_handlers(); m_canvas->bind_event_handlers();
#else m_canvas->allow_multisample(OpenGLManager::can_multisample());
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_canvas->allow_multisample(GLCanvas3DManager::can_multisample());
m_canvas->set_config(m_config); m_canvas->set_config(m_config);
m_canvas->set_model(model); m_canvas->set_model(model);
m_canvas->set_process(m_process); m_canvas->set_process(m_process);
@ -374,19 +325,11 @@ Preview::~Preview()
{ {
unbind_event_handlers(); unbind_event_handlers();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_canvas != nullptr) if (m_canvas != nullptr)
delete m_canvas; delete m_canvas;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (m_canvas_widget != nullptr) if (m_canvas_widget != nullptr)
{
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
_3DScene::remove_canvas(m_canvas_widget);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
delete m_canvas_widget; delete m_canvas_widget;
m_canvas = nullptr;
}
} }
void Preview::set_as_dirty() void Preview::set_as_dirty()

View File

@ -34,9 +34,7 @@ class GLCanvas3D;
class GLToolbar; class GLToolbar;
class Bed3D; class Bed3D;
struct Camera; struct Camera;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
class Plater; class Plater;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
class View3D : public wxPanel class View3D : public wxPanel
{ {
@ -44,11 +42,7 @@ class View3D : public wxPanel
GLCanvas3D* m_canvas; GLCanvas3D* m_canvas;
public: public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process); View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
#else
View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
virtual ~View3D(); virtual ~View3D();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
@ -76,11 +70,7 @@ public:
void render(); void render();
private: private:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process); bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
#else
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
}; };
class Preview : public wxPanel class Preview : public wxPanel
@ -120,13 +110,8 @@ class Preview : public wxPanel
DoubleSlider::Control* m_slider {nullptr}; DoubleSlider::Control* m_slider {nullptr};
public: public:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = []() {}); BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = []() {});
#else
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = [](){});
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
virtual ~Preview(); virtual ~Preview();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
@ -153,11 +138,7 @@ public:
bool is_loaded() const { return m_loaded; } bool is_loaded() const { return m_loaded; }
private: private:
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool init(wxWindow* parent, Model* model); bool init(wxWindow* parent, Model* model);
#else
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
void bind_event_handlers(); void bind_event_handlers();
void unbind_event_handlers(); void unbind_event_handlers();

View File

@ -220,11 +220,7 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
if (! m_c->raycaster()->raycaster()) if (! m_c->raycaster()->raycaster())
return false; return false;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Camera& camera = wxGetApp().plater()->get_camera(); const Camera& camera = wxGetApp().plater()->get_camera();
#else
const Camera& camera = m_parent.get_camera();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const Selection& selection = m_parent.get_selection(); const Selection& selection = m_parent.get_selection();
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin()); const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
Geometry::Transformation trafo = volume->get_instance_transformation(); Geometry::Transformation trafo = volume->get_instance_transformation();

View File

@ -2,9 +2,7 @@
#include "GLGizmosManager.hpp" #include "GLGizmosManager.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp" #include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/3DScene.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#include "slic3r/GUI/Camera.hpp" #include "slic3r/GUI/Camera.hpp"
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/GUI_App.hpp"
#include "slic3r/GUI/GUI_ObjectManipulation.hpp" #include "slic3r/GUI/GUI_ObjectManipulation.hpp"
#include "slic3r/GUI/PresetBundle.hpp" #include "slic3r/GUI/PresetBundle.hpp"
@ -1067,13 +1065,8 @@ void GLGizmosManager::do_render_overlay() const
float cnv_w = (float)m_parent.get_canvas_size().get_width(); float cnv_w = (float)m_parent.get_canvas_size().get_width();
float cnv_h = (float)m_parent.get_canvas_size().get_height(); float cnv_h = (float)m_parent.get_canvas_size().get_height();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float zoom = (float)wxGetApp().plater()->get_camera().get_zoom(); float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
#else
float zoom = (float)m_parent.get_camera().get_zoom();
float inv_zoom = (float)m_parent.get_camera().get_inv_zoom();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
float height = get_scaled_total_height(); float height = get_scaled_total_height();
float width = get_scaled_total_width(); float width = get_scaled_total_width();
@ -1124,11 +1117,7 @@ void GLGizmosManager::do_render_overlay() const
GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } }); GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
if (idx == m_current) { if (idx == m_current) {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height(); float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height();
#else
float toolbar_top = cnv_h - m_parent.get_view_toolbar_height();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top); gizmo->render_input_window(width, 0.5f * cnv_h - zoomed_top_y * zoom, toolbar_top);
} }
zoomed_top_y -= zoomed_stride_y; zoomed_top_y -= zoomed_stride_y;

View File

@ -7,6 +7,7 @@
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/filesystem.hpp>
#include <wx/string.h> #include <wx/string.h>
#include <wx/event.h> #include <wx/event.h>
@ -27,10 +28,22 @@
#include "I18N.hpp" #include "I18N.hpp"
#include "Search.hpp" #include "Search.hpp"
#include "../Utils/MacDarkMode.hpp"
#include "nanosvg/nanosvg.h"
#include "nanosvg/nanosvgrast.h"
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
static const std::map<const char, std::string> font_icons = {
{ImGui::PrintIconMarker , "cog" },
{ImGui::PrinterIconMarker , "printer" },
{ImGui::PrinterSlaIconMarker, "sla_printer"},
{ImGui::FilamentIconMarker , "spool" },
{ImGui::MaterialIconMarker , "resin" }
};
ImGuiWrapper::ImGuiWrapper() ImGuiWrapper::ImGuiWrapper()
: m_glyph_ranges(nullptr) : m_glyph_ranges(nullptr)
, m_font_cjk(false) , m_font_cjk(false)
@ -614,8 +627,9 @@ static void process_key_down(ImGuiKey imgui_key, std::function<void()> f)
} }
void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str, void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str,
Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel) Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized)
{ {
int& hovered_id = view_params.hovered_id;
// ImGui::ListBoxHeader("", size); // ImGui::ListBoxHeader("", size);
{ {
// rewrote part of function to add a TextInput instead of label Text // rewrote part of function to add a TextInput instead of label Text
@ -655,7 +669,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
ImGui::InputTextEx("", NULL, search_str, 20, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL); ImGui::InputTextEx("", NULL, search_str, 20, search_size, ImGuiInputTextFlags_AutoSelectAll, NULL, NULL);
edited = ImGui::IsItemEdited(); edited = ImGui::IsItemEdited();
if (edited) if (edited)
view_params.hovered_id = -1; hovered_id = 0;
process_key_down(ImGuiKey_Escape, [&selected, search_str, str]() { process_key_down(ImGuiKey_Escape, [&selected, search_str, str]() {
// use 9999 to mark selection as a Esc key // use 9999 to mark selection as a Esc key
@ -671,7 +685,6 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
const char* item_text; const char* item_text;
const char* tooltip; const char* tooltip;
int mouse_hovered = -1; int mouse_hovered = -1;
int& hovered_id = view_params.hovered_id;
while (items_getter(i, &item_text, &tooltip)) while (items_getter(i, &item_text, &tooltip))
{ {
@ -679,7 +692,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", /*item_text*/tooltip); ImGui::SetTooltip("%s", /*item_text*/tooltip);
view_params.hovered_id = -1; hovered_id = -1;
mouse_hovered = i; mouse_hovered = i;
} }
@ -688,8 +701,6 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
i++; i++;
} }
scroll_y(mouse_hovered);
// Process mouse wheel // Process mouse wheel
if (mouse_hovered > 0) if (mouse_hovered > 0)
process_mouse_wheel(mouse_wheel); process_mouse_wheel(mouse_wheel);
@ -699,7 +710,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
if (mouse_hovered > 0) if (mouse_hovered > 0)
scroll_up(); scroll_up();
else { else {
if (hovered_id > 0 && hovered_id != size_t(-1)) if (hovered_id > 0)
--hovered_id; --hovered_id;
scroll_y(hovered_id); scroll_y(hovered_id);
} }
@ -709,9 +720,9 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
if (mouse_hovered > 0) if (mouse_hovered > 0)
scroll_down(); scroll_down();
else { else {
if (hovered_id == size_t(-1)) if (hovered_id < 0)
hovered_id = 0; hovered_id = 0;
else if (hovered_id < size_t(i - 1)) else if (hovered_id < i - 1)
++hovered_id; ++hovered_id;
scroll_y(hovered_id); scroll_y(hovered_id);
} }
@ -735,9 +746,10 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
// add checkboxes for show/hide Categories and Groups // add checkboxes for show/hide Categories and Groups
text(_L("Use for search")+":"); text(_L("Use for search")+":");
check_box(_L("Type"), view_params.type);
check_box(_L("Category"), view_params.category); check_box(_L("Category"), view_params.category);
check_box(_L("Group"), view_params.group); check_box(_L("Group"), view_params.group);
if (is_localized)
check_box(_L("Search in English"), view_params.english);
} }
void ImGuiWrapper::disabled_begin(bool disabled) void ImGuiWrapper::disabled_begin(bool disabled)
@ -791,6 +803,59 @@ static const ImWchar ranges_keyboard_shortcuts[] =
}; };
#endif // __APPLE__ #endif // __APPLE__
std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height)
{
#ifdef __APPLE__
// Note: win->GetContentScaleFactor() is not used anymore here because it tends to
// return bogus results quite often (such as 1.0 on Retina or even 0.0).
// We're using the max scaling factor across all screens because it's very likely to be good enough.
double scale = mac_max_scaling_factor();
#else
double scale = 1.0;
#endif
std::vector<unsigned char> empty_vector;
#ifdef __WXMSW__
std::string folder = "white\\";
#else
std::string folder = "white/";
#endif
if (!boost::filesystem::exists(Slic3r::var(folder + bitmap_name + ".svg")))
folder.clear();
NSVGimage* image = ::nsvgParseFromFile(Slic3r::var(folder + bitmap_name + ".svg").c_str(), "px", 96.0f);
if (image == nullptr)
return empty_vector;
target_height != 0 ? target_height *= scale : target_width *= scale;
float svg_scale = target_height != 0 ?
(float)target_height / image->height : target_width != 0 ?
(float)target_width / image->width : 1;
int width = (int)(svg_scale * image->width + 0.5f);
int height = (int)(svg_scale * image->height + 0.5f);
int n_pixels = width * height;
if (n_pixels <= 0) {
::nsvgDelete(image);
return empty_vector;
}
NSVGrasterizer* rast = ::nsvgCreateRasterizer();
if (rast == nullptr) {
::nsvgDelete(image);
return empty_vector;
}
std::vector<unsigned char> data(n_pixels * 4, 0);
::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4);
::nsvgDeleteRasterizer(rast);
::nsvgDelete(image);
return data;
}
void ImGuiWrapper::init_font(bool compress) void ImGuiWrapper::init_font(bool compress)
{ {
destroy_font(); destroy_font();
@ -829,11 +894,33 @@ void ImGuiWrapper::init_font(bool compress)
} }
#endif #endif
float font_scale = m_font_size/15;
int icon_sz = lround(16 * font_scale); // default size of icon is 16 px
int rect_id = io.Fonts->CustomRects.Size; // id of the rectangle added next
// add rectangles for the icons to the font atlas
for (auto& icon : font_icons)
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
// Build texture atlas // Build texture atlas
unsigned char* pixels; unsigned char* pixels;
int width, height; int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
// Fill rectangles from the SVG-icons
for (auto icon : font_icons) {
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) {
std::vector<unsigned char> raw_data = load_svg(icon.second, icon_sz, icon_sz);
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);
for (int x = 0; x < icon_sz; x++)
*pOut++ = *pIn++;
}
}
rect_id++;
}
// Upload texture to graphics system // Upload texture to graphics system
GLint last_texture; GLint last_texture;
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));

View File

@ -79,7 +79,7 @@ public:
bool combo(const wxString& label, const std::vector<std::string>& options, int& selection); // Use -1 to not mark any option as selected bool combo(const wxString& label, const std::vector<std::string>& options, int& selection); // Use -1 to not mark any option as selected
bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel); bool undo_redo_list(const ImVec2& size, const bool is_undo, bool (*items_getter)(const bool, int, const char**), int& hovered, int& selected, int& mouse_wheel);
void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str, void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str,
Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel); Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized);
void disabled_begin(bool disabled); void disabled_begin(bool disabled);
void disabled_end(); void disabled_end();
@ -96,6 +96,7 @@ private:
void render_draw_data(ImDrawData *draw_data); void render_draw_data(ImDrawData *draw_data);
bool display_initialized() const; bool display_initialized() const;
void destroy_font(); void destroy_font();
std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height);
static const char* clipboard_get(void* user_data); static const char* clipboard_get(void* user_data);
static void clipboard_set(void* user_data, const char* text); static void clipboard_set(void* user_data, const char* text);

View File

@ -90,10 +90,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
// initialize layout // initialize layout
auto sizer = new wxBoxSizer(wxVERTICAL); auto sizer = new wxBoxSizer(wxVERTICAL);
if (m_plater) if (m_plater && m_layout != slOld)
sizer->Add(m_plater, 1, wxEXPAND); sizer->Add(m_plater, 1, wxEXPAND);
if (m_tabpanel)
if (m_tabpanel && m_layout != slDlg)
sizer->Add(m_tabpanel, 1, wxEXPAND); sizer->Add(m_tabpanel, 1, wxEXPAND);
sizer->SetSizeHints(this); sizer->SetSizeHints(this);
SetSizer(sizer); SetSizer(sizer);
Fit(); Fit();
@ -212,7 +214,6 @@ void MainFrame::shutdown()
if (m_plater) if (m_plater)
m_plater->stop_jobs(); m_plater->stop_jobs();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
// Unbinding of wxWidgets event handling in canvases needs to be done here because on MAC, // Unbinding of wxWidgets event handling in canvases needs to be done here because on MAC,
// when closing the application using Command+Q, a mouse event is triggered after this lambda is completed, // when closing the application using Command+Q, a mouse event is triggered after this lambda is completed,
// causing a crash // causing a crash
@ -221,7 +222,6 @@ void MainFrame::shutdown()
// Cleanup of canvases' volumes needs to be done here or a crash may happen on some Linux Debian flavours // Cleanup of canvases' volumes needs to be done here or a crash may happen on some Linux Debian flavours
// see: https://github.com/prusa3d/PrusaSlicer/issues/3964 // see: https://github.com/prusa3d/PrusaSlicer/issues/3964
if (m_plater) m_plater->reset_canvas_volumes(); if (m_plater) m_plater->reset_canvas_volumes();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// Weird things happen as the Paint messages are floating around the windows being destructed. // Weird things happen as the Paint messages are floating around the windows being destructed.
// Avoid the Paint messages by hiding the main window. // Avoid the Paint messages by hiding the main window.
@ -229,6 +229,9 @@ void MainFrame::shutdown()
// In addition, there were some crashes due to the Paint events sent to already destructed windows. // In addition, there were some crashes due to the Paint events sent to already destructed windows.
this->Show(false); this->Show(false);
if (m_settings_dialog)
m_settings_dialog->Destroy();
// Stop the background thread (Windows and Linux). // Stop the background thread (Windows and Linux).
// Disconnect from a 3DConnextion driver (OSX). // Disconnect from a 3DConnextion driver (OSX).
m_plater->get_mouse3d_controller().shutdown(); m_plater->get_mouse3d_controller().shutdown();
@ -244,9 +247,6 @@ void MainFrame::shutdown()
wxGetApp().app_config->save(); wxGetApp().app_config->save();
// if (m_plater) // if (m_plater)
// m_plater->print = undef; // m_plater->print = undef;
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
_3DScene::remove_all_canvases();
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
// Slic3r::GUI::deregister_on_request_update_callback(); // Slic3r::GUI::deregister_on_request_update_callback();
// set to null tabs and a plater // set to null tabs and a plater
@ -289,12 +289,25 @@ void MainFrame::update_title()
void MainFrame::init_tabpanel() void MainFrame::init_tabpanel()
{ {
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10 m_layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? slOld :
// with multiple high resolution displays connected. wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? slNew :
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? slDlg : slOld;
// From the very beginning the Print settings should be selected
m_last_selected_tab = m_layout == slDlg ? 0 : 1;
if (m_layout == slDlg) {
m_settings_dialog = new SettingsDialog(this);
m_tabpanel = m_settings_dialog->get_tabpanel();
}
else {
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
// with multiple high resolution displays connected.
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList #ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
#endif #endif
}
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
auto panel = m_tabpanel->GetCurrentPage(); auto panel = m_tabpanel->GetCurrentPage();
@ -307,17 +320,22 @@ void MainFrame::init_tabpanel()
// On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered // On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered
// before the MainFrame is fully set up. // before the MainFrame is fully set up.
static_cast<Tab*>(panel)->OnActivate(); static_cast<Tab*>(panel)->OnActivate();
m_last_selected_tab = m_tabpanel->GetSelection();
} }
else else
select_tab(0); select_tab(0);
}); });
//! m_plater = new Slic3r::GUI::Plater(m_tabpanel, this); if (m_layout == slOld) {
m_plater = new Plater(this, this); m_plater = new Plater(m_tabpanel, this);
m_tabpanel->AddPage(m_plater, _L("Plater"));
}
else {
m_plater = new Plater(this, this);
if (m_layout == slNew)
m_tabpanel->AddPage(new wxPanel(m_tabpanel), _L("Plater")); // empty panel just for Plater tab
}
wxGetApp().plater_ = m_plater; wxGetApp().plater_ = m_plater;
// m_tabpanel->AddPage(m_plater, _(L("Plater")));
m_tabpanel->AddPage(new wxPanel(m_tabpanel), _L("Plater")); // empty panel just for Plater tab
wxGetApp().obj_list()->create_popup_menus(); wxGetApp().obj_list()->create_popup_menus();
@ -343,13 +361,6 @@ void MainFrame::init_tabpanel()
} }
} }
void MainFrame::switch_to(bool plater)
{
this->m_plater->Show(plater);
this->m_tabpanel->Show(!plater);
this->Layout();
}
void MainFrame::create_preset_tabs() void MainFrame::create_preset_tabs()
{ {
wxGetApp().update_label_colours_from_appconfig(); wxGetApp().update_label_colours_from_appconfig();
@ -465,6 +476,11 @@ bool MainFrame::can_slice() const
bool MainFrame::can_change_view() const bool MainFrame::can_change_view() const
{ {
if (m_layout == slNew)
return m_plater->IsShown();
if (m_layout == slDlg)
return true;
// slOld layout mode
int page_id = m_tabpanel->GetSelection(); int page_id = m_tabpanel->GetSelection();
return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr; return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr;
} }
@ -763,25 +779,21 @@ void MainFrame::init_menubar()
// Window menu // Window menu
auto windowMenu = new wxMenu(); auto windowMenu = new wxMenu();
{ {
//! size_t tab_offset = 0;
if (m_plater) { if (m_plater) {
append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")), append_menu_item(windowMenu, wxID_HIGHEST + 1, _(L("&Plater Tab")) + "\tCtrl+1", _(L("Show the plater")),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*(size_t)(-1)*/0); }, "plater", nullptr, [this](wxCommandEvent&) { select_tab(0); }, "plater", nullptr,
[this]() {return true; }, this); [this]() {return true; }, this);
//! tab_offset += 1;
//! }
//! if (tab_offset > 0) {
windowMenu->AppendSeparator(); windowMenu->AppendSeparator();
} }
append_menu_item(windowMenu, wxID_HIGHEST + 2, _(L("P&rint Settings Tab")) + "\tCtrl+2", _(L("Show the print settings")), append_menu_item(windowMenu, wxID_HIGHEST + 2, _(L("P&rint Settings Tab")) + "\tCtrl+2", _(L("Show the print settings")),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 0*/1); }, "cog", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(1); }, "cog", nullptr,
[this]() {return true; }, this); [this]() {return true; }, this);
wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 3, _(L("&Filament Settings Tab")) + "\tCtrl+3", _(L("Show the filament settings")), wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 3, _(L("&Filament Settings Tab")) + "\tCtrl+3", _(L("Show the filament settings")),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 1*/2); }, "spool", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(2); }, "spool", nullptr,
[this]() {return true; }, this); [this]() {return true; }, this);
m_changeable_menu_items.push_back(item_material_tab); m_changeable_menu_items.push_back(item_material_tab);
wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")), wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 4, _(L("Print&er Settings Tab")) + "\tCtrl+4", _(L("Show the printer settings")),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(/*tab_offset + 2*/3); }, "printer", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(3); }, "printer", nullptr,
[this]() {return true; }, this); [this]() {return true; }, this);
m_changeable_menu_items.push_back(item_printer_tab); m_changeable_menu_items.push_back(item_printer_tab);
if (m_plater) { if (m_plater) {
@ -1245,17 +1257,32 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
#endif #endif
} }
void MainFrame::select_tab(size_t tab) void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
{ {
if (tab == /*(size_t)(-1)*/0) { if (m_layout == slDlg) {
if (m_plater && !m_plater->IsShown()) if (tab==0) {
this->switch_to(true); if (m_settings_dialog->IsShown())
this->SetFocus();
return;
}
// Show/Activate Settings Dialog
if (m_settings_dialog->IsShown())
#ifdef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
m_settings_dialog->Hide();
#else
m_settings_dialog->SetFocus();
else
#endif
m_settings_dialog->Show();
} }
else { else if (m_layout == slNew) {
if (m_plater && m_plater->IsShown()) m_plater->Show(tab == 0);
switch_to(false); m_tabpanel->Show(tab != 0);
m_tabpanel->SetSelection(tab); Layout();
} }
// when tab == -1, it means we should to show the last selected tab
m_tabpanel->SetSelection(tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == slDlg && tab != 0) ? tab-1 : tab);
} }
// Set a camera direction, zoom to all objects. // Set a camera direction, zoom to all objects.
@ -1360,5 +1387,79 @@ std::string MainFrame::get_dir_name(const wxString &full_name) const
return boost::filesystem::path(full_name.wx_str()).parent_path().string(); return boost::filesystem::path(full_name.wx_str()).parent_path().string();
} }
// ----------------------------------------------------------------------------
// SettingsDialog
// ----------------------------------------------------------------------------
SettingsDialog::SettingsDialog(MainFrame* mainframe)
: DPIDialog(nullptr, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Settings")),
m_main_frame(mainframe)
{
this->SetFont(wxGetApp().normal_font());
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
this->SetBackgroundColour(bgr_clr);
// Load the icon either from the exe, or from the ico file.
#if _WIN32
{
TCHAR szExeFileName[MAX_PATH];
GetModuleFileName(nullptr, szExeFileName, MAX_PATH);
SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO));
}
#else
SetIcon(wxIcon(var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG));
#endif // _WIN32
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
// with multiple high resolution displays connected.
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
#ifndef __WXOSX__ // Don't call SetFont under OSX to avoid name cutting in ObjectList
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
#endif
m_tabpanel->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& evt) {
if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
switch (evt.GetKeyCode()) {
case '1': { m_main_frame->select_tab(0); break; }
case '2': { m_main_frame->select_tab(1); break; }
case '3': { m_main_frame->select_tab(2); break; }
case '4': { m_main_frame->select_tab(3); break; }
default:break;
}
}
});
// initialize layout
auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_tabpanel, 1, wxEXPAND);
sizer->SetSizeHints(this);
SetSizer(sizer);
Fit();
const wxSize min_size = wxSize(85 * em_unit(), 50 * em_unit());
#ifdef __APPLE__
// Using SetMinSize() on Mac messes up the window position in some cases
// cf. https://groups.google.com/forum/#!topic/wx-users/yUKPBBfXWO0
SetSize(min_size);
#else
SetMinSize(min_size);
SetSize(GetMinSize());
#endif
Layout();
}
void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
{
const int& em = em_unit();
const wxSize& size = wxSize(85 * em, 50 * em);
SetMinSize(size);
Fit();
Refresh();
}
} // GUI } // GUI
} // Slic3r } // Slic3r

View File

@ -43,6 +43,23 @@ struct PresetTab {
PrinterTechnology technology; PrinterTechnology technology;
}; };
// ----------------------------------------------------------------------------
// SettingsDialog
// ----------------------------------------------------------------------------
class SettingsDialog : public DPIDialog
{
wxNotebook* m_tabpanel { nullptr };
MainFrame* m_main_frame {nullptr };
public:
SettingsDialog(MainFrame* mainframe);
~SettingsDialog() {}
wxNotebook* get_tabpanel() { return m_tabpanel; }
protected:
void on_dpi_changed(const wxRect& suggested_rect) override;
};
class MainFrame : public DPIFrame class MainFrame : public DPIFrame
{ {
bool m_loaded {false}; bool m_loaded {false};
@ -57,6 +74,8 @@ class MainFrame : public DPIFrame
PrintHostQueueDialog *m_printhost_queue_dlg; PrintHostQueueDialog *m_printhost_queue_dlg;
size_t m_last_selected_tab;
std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const; std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const;
std::string get_dir_name(const wxString &full_name) const; std::string get_dir_name(const wxString &full_name) const;
@ -94,6 +113,12 @@ class MainFrame : public DPIFrame
wxFileHistory m_recent_projects; wxFileHistory m_recent_projects;
enum SettingsLayout {
slOld = 0,
slNew,
slDlg,
} m_layout;
protected: protected:
virtual void on_dpi_changed(const wxRect &suggested_rect); virtual void on_dpi_changed(const wxRect &suggested_rect);
@ -109,7 +134,6 @@ public:
void update_title(); void update_title();
void init_tabpanel(); void init_tabpanel();
void switch_to(bool plater);
void create_preset_tabs(); void create_preset_tabs();
void add_created_tab(Tab* panel); void add_created_tab(Tab* panel);
void init_menubar(); void init_menubar();
@ -130,7 +154,9 @@ public:
void export_configbundle(); void export_configbundle();
void load_configbundle(wxString file = wxEmptyString); void load_configbundle(wxString file = wxEmptyString);
void load_config(const DynamicPrintConfig& config); void load_config(const DynamicPrintConfig& config);
void select_tab(size_t tab); // Select tab in m_tabpanel
// When tab == -1, will be selected last selected tab
void select_tab(size_t tab = size_t(-1));
void select_view(const std::string& direction); void select_view(const std::string& direction);
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig // Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
void on_config_changed(DynamicPrintConfig* cfg) const ; void on_config_changed(DynamicPrintConfig* cfg) const ;
@ -141,6 +167,7 @@ public:
Plater* m_plater { nullptr }; Plater* m_plater { nullptr };
wxNotebook* m_tabpanel { nullptr }; wxNotebook* m_tabpanel { nullptr };
SettingsDialog* m_settings_dialog { nullptr };
wxProgressDialog* m_progress_dialog { nullptr }; wxProgressDialog* m_progress_dialog { nullptr };
std::shared_ptr<ProgressStatusBar> m_statusbar; std::shared_ptr<ProgressStatusBar> m_statusbar;

View File

@ -1710,10 +1710,11 @@ bool BitmapChoiceRenderer::Render(wxRect rect, wxDC* dc, int state)
{ {
dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2); dc->DrawBitmap(icon, rect.x, rect.y + (rect.height - icon.GetHeight()) / 2);
xoffset = icon.GetWidth() + 4; xoffset = icon.GetWidth() + 4;
if (rect.height==0)
rect.height= icon.GetHeight();
} }
if (rect.height==0)
rect.height= icon.GetHeight();
RenderText(m_value.GetText(), xoffset, rect, dc, state); RenderText(m_value.GetText(), xoffset, rect, dc, state);
return true; return true;

View File

@ -1,23 +1,18 @@
#include "libslic3r/libslic3r.h" #include "libslic3r/libslic3r.h"
#include "GLCanvas3DManager.hpp" #include "OpenGLManager.hpp"
#include "../../slic3r/GUI/GUI.hpp"
#include "../../slic3r/GUI/AppConfig.hpp" #include "GUI.hpp"
#include "../../slic3r/GUI/GLCanvas3D.hpp" #include "I18N.hpp"
#include "3DScene.hpp"
#include <GL/glew.h> #include <GL/glew.h>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <wx/glcanvas.h>
#include <wx/timer.h>
#include <wx/msgdlg.h>
#include <vector> #include <wx/glcanvas.h>
#include <string> #include <wx/msgdlg.h>
#include <iostream>
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__ #ifdef __APPLE__
@ -33,20 +28,7 @@
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
#if !ENABLE_NON_STATIC_CANVAS_MANAGER const std::string& OpenGLManager::GLInfo::get_version() const
GLCanvas3DManager::GLInfo::GLInfo()
: m_detected(false)
, m_version("")
, m_glsl_version("")
, m_vendor("")
, m_renderer("")
, m_max_tex_size(0)
, m_max_anisotropy(0.0f)
{
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
const std::string& GLCanvas3DManager::GLInfo::get_version() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -54,7 +36,7 @@ const std::string& GLCanvas3DManager::GLInfo::get_version() const
return m_version; return m_version;
} }
const std::string& GLCanvas3DManager::GLInfo::get_glsl_version() const const std::string& OpenGLManager::GLInfo::get_glsl_version() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -62,7 +44,7 @@ const std::string& GLCanvas3DManager::GLInfo::get_glsl_version() const
return m_glsl_version; return m_glsl_version;
} }
const std::string& GLCanvas3DManager::GLInfo::get_vendor() const const std::string& OpenGLManager::GLInfo::get_vendor() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -70,7 +52,7 @@ const std::string& GLCanvas3DManager::GLInfo::get_vendor() const
return m_vendor; return m_vendor;
} }
const std::string& GLCanvas3DManager::GLInfo::get_renderer() const const std::string& OpenGLManager::GLInfo::get_renderer() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -78,7 +60,7 @@ const std::string& GLCanvas3DManager::GLInfo::get_renderer() const
return m_renderer; return m_renderer;
} }
int GLCanvas3DManager::GLInfo::get_max_tex_size() const int OpenGLManager::GLInfo::get_max_tex_size() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -93,7 +75,7 @@ int GLCanvas3DManager::GLInfo::get_max_tex_size() const
#endif // __APPLE__ #endif // __APPLE__
} }
float GLCanvas3DManager::GLInfo::get_max_anisotropy() const float OpenGLManager::GLInfo::get_max_anisotropy() const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -101,7 +83,7 @@ float GLCanvas3DManager::GLInfo::get_max_anisotropy() const
return m_max_anisotropy; return m_max_anisotropy;
} }
void GLCanvas3DManager::GLInfo::detect() const void OpenGLManager::GLInfo::detect() const
{ {
const char* data = (const char*)::glGetString(GL_VERSION); const char* data = (const char*)::glGetString(GL_VERSION);
if (data != nullptr) if (data != nullptr)
@ -132,7 +114,7 @@ void GLCanvas3DManager::GLInfo::detect() const
m_detected = true; m_detected = true;
} }
bool GLCanvas3DManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const bool OpenGLManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -163,7 +145,7 @@ bool GLCanvas3DManager::GLInfo::is_version_greater_or_equal_to(unsigned int majo
return gl_minor >= minor; return gl_minor >= minor;
} }
std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool extensions) const std::string OpenGLManager::GLInfo::to_string(bool format_as_html, bool extensions) const
{ {
if (!m_detected) if (!m_detected)
detect(); detect();
@ -203,34 +185,20 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten
return out.str(); return out.str();
} }
GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; OpenGLManager::GLInfo OpenGLManager::s_gl_info;
bool GLCanvas3DManager::s_compressed_textures_supported = false; bool OpenGLManager::s_compressed_textures_supported = false;
#if ENABLE_NON_STATIC_CANVAS_MANAGER OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown;
GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::EMultisampleState::Unknown; OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
GLCanvas3DManager::EFramebufferType GLCanvas3DManager::s_framebuffers_type = GLCanvas3DManager::EFramebufferType::Unknown;
#else
GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown;
GLCanvas3DManager::EFramebufferType GLCanvas3DManager::s_framebuffers_type = GLCanvas3DManager::FB_None;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__ #ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
GLCanvas3DManager::OSInfo GLCanvas3DManager::s_os_info; OpenGLManager::OSInfo OpenGLManager::s_os_info;
#endif // __APPLE__ #endif // __APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#if !ENABLE_NON_STATIC_CANVAS_MANAGER OpenGLManager::~OpenGLManager()
GLCanvas3DManager::GLCanvas3DManager()
: m_context(nullptr)
, m_gl_initialized(false)
{ {
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
GLCanvas3DManager::~GLCanvas3DManager()
{
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__ #ifdef __APPLE__
// This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets // This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets
@ -248,116 +216,29 @@ GLCanvas3DManager::~GLCanvas3DManager()
} }
#endif //__APPLE__ #endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5 #endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#else
this->destroy();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
#if !ENABLE_NON_STATIC_CANVAS_MANAGER bool OpenGLManager::init_gl()
bool GLCanvas3DManager::add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
{
if (canvas == nullptr)
return false;
if (do_get_canvas(canvas) != m_canvases.end())
return false;
GLCanvas3D* canvas3D = new GLCanvas3D(canvas, bed, camera, view_toolbar);
if (canvas3D == nullptr)
return false;
canvas3D->bind_event_handlers();
if (m_context == nullptr)
{
m_context = new wxGLContext(canvas);
if (m_context == nullptr)
return false;
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
s_os_info.major = wxPlatformInfo::Get().GetOSMajorVersion();
s_os_info.minor = wxPlatformInfo::Get().GetOSMinorVersion();
s_os_info.micro = wxPlatformInfo::Get().GetOSMicroVersion();
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
}
canvas3D->set_context(m_context);
m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D));
return true;
}
bool GLCanvas3DManager::remove(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = do_get_canvas(canvas);
if (it == m_canvases.end())
return false;
it->second->unbind_event_handlers();
delete it->second;
m_canvases.erase(it);
return true;
}
void GLCanvas3DManager::remove_all()
{
for (CanvasesMap::value_type& item : m_canvases)
{
item.second->unbind_event_handlers();
delete item.second;
}
m_canvases.clear();
}
size_t GLCanvas3DManager::count() const
{
return m_canvases.size();
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_NON_STATIC_CANVAS_MANAGER
bool GLCanvas3DManager::init_gl()
#else
void GLCanvas3DManager::init_gl()
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
if (!m_gl_initialized) if (!m_gl_initialized)
{ {
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (glewInit() != GLEW_OK) if (glewInit() != GLEW_OK)
{ {
BOOST_LOG_TRIVIAL(error) << "Unable to init glew library"; BOOST_LOG_TRIVIAL(error) << "Unable to init glew library";
return false; return false;
} }
#else
glewInit();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_gl_initialized = true; m_gl_initialized = true;
if (GLEW_EXT_texture_compression_s3tc) if (GLEW_EXT_texture_compression_s3tc)
s_compressed_textures_supported = true; s_compressed_textures_supported = true;
else else
s_compressed_textures_supported = false; s_compressed_textures_supported = false;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (GLEW_ARB_framebuffer_object) if (GLEW_ARB_framebuffer_object)
s_framebuffers_type = EFramebufferType::Arb; s_framebuffers_type = EFramebufferType::Arb;
else if (GLEW_EXT_framebuffer_object) else if (GLEW_EXT_framebuffer_object)
s_framebuffers_type = EFramebufferType::Ext; s_framebuffers_type = EFramebufferType::Ext;
else else
s_framebuffers_type = EFramebufferType::Unknown; s_framebuffers_type = EFramebufferType::Unknown;
#else
if (GLEW_ARB_framebuffer_object)
s_framebuffers_type = FB_Arb;
else if (GLEW_EXT_framebuffer_object)
s_framebuffers_type = FB_Ext;
else
s_framebuffers_type = FB_None;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) {
// Complain about the OpenGL version. // Complain about the OpenGL version.
@ -365,22 +246,19 @@ void GLCanvas3DManager::init_gl()
_utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" _utf8(L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n"
"while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str()); "while OpenGL version %s, render %s, vendor %s was detected."))) % s_gl_info.get_version() % s_gl_info.get_renderer() % s_gl_info.get_vendor()).str());
message += "\n"; message += "\n";
message += _(L("You may need to update your graphics card driver.")); message += _L("You may need to update your graphics card driver.");
#ifdef _WIN32 #ifdef _WIN32
message += "\n"; message += "\n";
message += _(L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw_renderer parameter.")); message += _L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw_renderer parameter.");
#endif #endif
wxMessageBox(message, wxString("PrusaSlicer - ") + _(L("Unsupported OpenGL version")), wxOK | wxICON_ERROR); wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Unsupported OpenGL version"), wxOK | wxICON_ERROR);
} }
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
return true; return true;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas)
wxGLContext* GLCanvas3DManager::init_glcontext(wxGLCanvas& canvas)
{ {
if (m_context == nullptr) if (m_context == nullptr)
{ {
@ -397,48 +275,8 @@ wxGLContext* GLCanvas3DManager::init_glcontext(wxGLCanvas& canvas)
} }
return m_context; return m_context;
} }
#else
bool GLCanvas3DManager::init(wxGLCanvas* canvas)
{
CanvasesMap::const_iterator it = do_get_canvas(canvas);
if (it != m_canvases.end())
return (it->second != nullptr) ? init(*it->second) : false;
else
return false;
}
void GLCanvas3DManager::destroy() wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent)
{
if (m_context != nullptr)
{
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// this is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5
// the crash is inside wxGLContext destructor
if (s_os_info.major == 10 && s_os_info.minor == 9 && s_os_info.micro == 5)
return;
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
delete m_context;
m_context = nullptr;
}
}
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
GLCanvas3D* GLCanvas3DManager::get_canvas(wxGLCanvas* canvas)
{
CanvasesMap::const_iterator it = do_get_canvas(canvas);
return (it != m_canvases.end()) ? it->second : nullptr;
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
#if ENABLE_NON_STATIC_CANVAS_MANAGER
wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow& parent)
#else
wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
int attribList[] = { int attribList[] = {
WX_GL_RGBA, WX_GL_RGBA,
@ -456,11 +294,7 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
0 0
}; };
#if ENABLE_NON_STATIC_CANVAS_MANAGER
if (s_multisample == EMultisampleState::Unknown) if (s_multisample == EMultisampleState::Unknown)
#else
if (s_multisample == MS_Unknown)
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
{ {
detect_multisample(attribList); detect_multisample(attribList);
// // debug output // // debug output
@ -470,42 +304,14 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
if (! can_multisample()) if (! can_multisample())
attribList[12] = 0; attribList[12] = 0;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
return new wxGLCanvas(&parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); return new wxGLCanvas(&parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
#else
return new wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
} }
#if !ENABLE_NON_STATIC_CANVAS_MANAGER void OpenGLManager::detect_multisample(int* attribList)
GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::do_get_canvas(wxGLCanvas* canvas)
{
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
}
GLCanvas3DManager::CanvasesMap::const_iterator GLCanvas3DManager::do_get_canvas(wxGLCanvas* canvas) const
{
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
}
bool GLCanvas3DManager::init(GLCanvas3D& canvas)
{
if (!m_gl_initialized)
init_gl();
return canvas.init();
}
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
void GLCanvas3DManager::detect_multisample(int* attribList)
{ {
int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER; int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
bool enable_multisample = wxVersion >= 30003; bool enable_multisample = wxVersion >= 30003;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? EMultisampleState::Enabled : EMultisampleState::Disabled; s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? EMultisampleState::Enabled : EMultisampleState::Disabled;
#else
s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? MS_Enabled : MS_Disabled;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows // Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows
// s_multisample = enable_multisample && wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample"); // s_multisample = enable_multisample && wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample");
} }

View File

@ -0,0 +1,106 @@
#ifndef slic3r_OpenGLManager_hpp_
#define slic3r_OpenGLManager_hpp_
class wxWindow;
class wxGLCanvas;
class wxGLContext;
namespace Slic3r {
namespace GUI {
class OpenGLManager
{
public:
enum class EFramebufferType : unsigned char
{
Unknown,
Arb,
Ext
};
class GLInfo
{
mutable bool m_detected{ false };
mutable int m_max_tex_size{ 0 };
mutable float m_max_anisotropy{ 0.0f };
mutable std::string m_version;
mutable std::string m_glsl_version;
mutable std::string m_vendor;
mutable std::string m_renderer;
public:
GLInfo() = default;
const std::string& get_version() const;
const std::string& get_glsl_version() const;
const std::string& get_vendor() const;
const std::string& get_renderer() const;
int get_max_tex_size() const;
float get_max_anisotropy() const;
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
std::string to_string(bool format_as_html, bool extensions) const;
private:
void detect() const;
};
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
struct OSInfo
{
int major{ 0 };
int minor{ 0 };
int micro{ 0 };
};
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
private:
enum class EMultisampleState : unsigned char
{
Unknown,
Enabled,
Disabled
};
bool m_gl_initialized{ false };
wxGLContext* m_context{ nullptr };
static GLInfo s_gl_info;
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
static OSInfo s_os_info;
#endif //__APPLE__
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
static bool s_compressed_textures_supported;
static EMultisampleState s_multisample;
static EFramebufferType s_framebuffers_type;
public:
OpenGLManager() = default;
~OpenGLManager();
bool init_gl();
wxGLContext* init_glcontext(wxGLCanvas& canvas);
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; }
static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }
static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; }
static wxGLCanvas* create_wxglcanvas(wxWindow& parent);
static const GLInfo& get_gl_info() { return s_gl_info; }
private:
static void detect_multisample(int* attribList);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_OpenGLManager_hpp_

View File

@ -105,6 +105,7 @@ void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& fiel
if (!m_show_modified_btns) { if (!m_show_modified_btns) {
field->m_Undo_btn->set_as_hidden(); field->m_Undo_btn->set_as_hidden();
field->m_Undo_to_sys_btn->set_as_hidden(); field->m_Undo_to_sys_btn->set_as_hidden();
field->m_blinking_bmp->Hide();
return; return;
} }

View File

@ -178,7 +178,7 @@ public:
if (staticbox) { if (staticbox) {
stb = new wxStaticBox(_parent, wxID_ANY, _(title)); stb = new wxStaticBox(_parent, wxID_ANY, _(title));
if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT); if (!wxOSX) stb->SetBackgroundStyle(wxBG_STYLE_PAINT);
stb->SetFont(wxGetApp().bold_font()); stb->SetFont(wxOSX ? wxGetApp().normal_font() : wxGetApp().bold_font());
} else } else
stb = nullptr; stb = nullptr;
sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));

View File

@ -77,11 +77,9 @@
#include "RemovableDriveManager.hpp" #include "RemovableDriveManager.hpp"
#include "InstanceCheck.hpp" #include "InstanceCheck.hpp"
#if ENABLE_NON_STATIC_CANVAS_MANAGER
#ifdef __APPLE__ #ifdef __APPLE__
#include "Gizmos/GLGizmosManager.hpp" #include "Gizmos/GLGizmosManager.hpp"
#endif // __APPLE__ #endif // __APPLE__
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
#include <wx/glcanvas.h> // Needs to be last because reasons :-/ #include <wx/glcanvas.h> // Needs to be last because reasons :-/
#include "WipeTowerDialog.hpp" #include "WipeTowerDialog.hpp"
@ -356,10 +354,10 @@ PresetBitmapComboBox(parent, wxSize(15 * wxGetApp().em_unit(), -1)),
if (page_id == wxNOT_FOUND) if (page_id == wxNOT_FOUND)
return; return;
wxGetApp().tab_panel()->ChangeSelection(page_id); wxGetApp().tab_panel()->SetSelection(page_id);
// Switch to Settings NotePad // Switch to Settings NotePad
wxGetApp().mainframe->switch_to(false); wxGetApp().mainframe->select_tab();
/* In a case of a multi-material printing, for editing another Filament Preset /* In a case of a multi-material printing, for editing another Filament Preset
* it's needed to select this preset for the "Filament settings" Tab * it's needed to select this preset for the "Filament settings" Tab
@ -1101,9 +1099,8 @@ void Sidebar::jump_to_option(size_t selected)
const Search::Option& opt = p->searcher.get_option(selected); const Search::Option& opt = p->searcher.get_option(selected);
wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category)); wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category));
// Switch to the Settings NotePad, if plater is shown // Switch to the Settings NotePad
if (p->plater->IsShown()) wxGetApp().mainframe->select_tab();
wxGetApp().mainframe->switch_to(false);
} }
ObjectManipulation* Sidebar::obj_manipul() ObjectManipulation* Sidebar::obj_manipul()
@ -1632,15 +1629,14 @@ struct Plater::priv
void set_current_canvas_as_dirty(); void set_current_canvas_as_dirty();
GLCanvas3D* get_current_canvas3D(); GLCanvas3D* get_current_canvas3D();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void unbind_canvas_event_handlers(); void unbind_canvas_event_handlers();
void reset_canvas_volumes(); void reset_canvas_volumes();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
bool init_view_toolbar(); bool init_view_toolbar();
void reset_all_gizmos(); void reset_all_gizmos();
void update_ui_from_settings(); void update_ui_from_settings();
void update_main_toolbar_tooltips();
std::shared_ptr<ProgressStatusBar> statusbar(); std::shared_ptr<ProgressStatusBar> statusbar();
std::string get_config(const std::string &key) const; std::string get_config(const std::string &key) const;
BoundingBoxf bed_shape_bb() const; BoundingBoxf bed_shape_bb() const;
@ -1861,7 +1857,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
sla_print.set_status_callback(statuscb); sla_print.set_status_callback(statuscb);
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this); this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
#if ENABLE_NON_STATIC_CANVAS_MANAGER
view3D = new View3D(q, &model, config, &background_process); view3D = new View3D(q, &model, config, &background_process);
preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); }); preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); });
@ -1869,10 +1864,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size // set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size); view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size);
#endif // __APPLE__ #endif // __APPLE__
#else
view3D = new View3D(q, bed, camera, view_toolbar, &model, config, &background_process);
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
panels.push_back(view3D); panels.push_back(view3D);
panels.push_back(preview); panels.push_back(preview);
@ -1973,10 +1964,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// Drop target: // Drop target:
q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
update_ui_from_settings();
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
q->Layout(); q->Layout();
set_current_panel(view3D); set_current_panel(view3D);
@ -2042,7 +2029,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// collapse sidebar according to saved value // collapse sidebar according to saved value
sidebar->collapse(wxGetApp().app_config->get("collapsed_sidebar") == "1"); bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
sidebar->collapse(is_collapsed);
// Update an enable of the collapse_toolbar: if sidebar is collapsed, then collapse_toolbar should be visible
if (is_collapsed)
wxGetApp().app_config->set("show_collapse_button", "1");
} }
Plater::priv::~priv() Plater::priv::~priv()
@ -2117,6 +2108,13 @@ void Plater::priv::update_ui_from_settings()
preview->get_canvas3d()->update_ui_from_settings(); preview->get_canvas3d()->update_ui_from_settings();
} }
// Called after the print technology was changed.
// Update the tooltips for "Switch to Settings" button in maintoolbar
void Plater::priv::update_main_toolbar_tooltips()
{
view3D->get_canvas3d()->update_tooltip_for_settings_item_in_main_toolbar();
}
std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar() std::shared_ptr<ProgressStatusBar> Plater::priv::statusbar()
{ {
return main_frame->m_statusbar; return main_frame->m_statusbar;
@ -3784,7 +3782,6 @@ GLCanvas3D* Plater::priv::get_current_canvas3D()
return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr); return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr);
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void Plater::priv::unbind_canvas_event_handlers() void Plater::priv::unbind_canvas_event_handlers()
{ {
if (view3D != nullptr) if (view3D != nullptr)
@ -3802,7 +3799,6 @@ void Plater::priv::reset_canvas_volumes()
if (preview != nullptr) if (preview != nullptr)
preview->get_canvas3d()->reset_volumes(); preview->get_canvas3d()->reset_volumes();
} }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
bool Plater::priv::init_view_toolbar() bool Plater::priv::init_view_toolbar()
{ {
@ -5245,7 +5241,6 @@ void Plater::set_current_canvas_as_dirty()
p->set_current_canvas_as_dirty(); p->set_current_canvas_as_dirty();
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void Plater::unbind_canvas_event_handlers() void Plater::unbind_canvas_event_handlers()
{ {
p->unbind_canvas_event_handlers(); p->unbind_canvas_event_handlers();
@ -5255,7 +5250,6 @@ void Plater::reset_canvas_volumes()
{ {
p->reset_canvas_volumes(); p->reset_canvas_volumes();
} }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
PrinterTechnology Plater::printer_technology() const PrinterTechnology Plater::printer_technology() const
{ {
@ -5278,6 +5272,10 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology)
if (wxGetApp().mainframe) if (wxGetApp().mainframe)
wxGetApp().mainframe->update_menubar(); wxGetApp().mainframe->update_menubar();
p->update_main_toolbar_tooltips();
p->sidebar->get_searcher().set_printer_technology(printer_technology);
} }
void Plater::changed_object(int obj_idx) void Plater::changed_object(int obj_idx)
@ -5413,7 +5411,6 @@ Camera& Plater::get_camera()
return p->camera; return p->camera;
} }
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Bed3D& Plater::get_bed() const const Bed3D& Plater::get_bed() const
{ {
return p->bed; return p->bed;
@ -5433,7 +5430,6 @@ GLToolbar& Plater::get_view_toolbar()
{ {
return p->view_toolbar; return p->view_toolbar;
} }
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const Mouse3DController& Plater::get_mouse3d_controller() const const Mouse3DController& Plater::get_mouse3d_controller() const
{ {

View File

@ -45,10 +45,8 @@ class ObjectList;
class GLCanvas3D; class GLCanvas3D;
class Mouse3DController; class Mouse3DController;
struct Camera; struct Camera;
#if ENABLE_NON_STATIC_CANVAS_MANAGER
class Bed3D; class Bed3D;
class GLToolbar; class GLToolbar;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>; using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
@ -280,10 +278,8 @@ public:
void find_new_position(const ModelInstancePtrs &instances, coord_t min_d); void find_new_position(const ModelInstancePtrs &instances, coord_t min_d);
void set_current_canvas_as_dirty(); void set_current_canvas_as_dirty();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
void unbind_canvas_event_handlers(); void unbind_canvas_event_handlers();
void reset_canvas_volumes(); void reset_canvas_volumes();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
PrinterTechnology printer_technology() const; PrinterTechnology printer_technology() const;
const DynamicPrintConfig * config() const; const DynamicPrintConfig * config() const;
@ -316,13 +312,11 @@ public:
const Camera& get_camera() const; const Camera& get_camera() const;
Camera& get_camera(); Camera& get_camera();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const Bed3D& get_bed() const; const Bed3D& get_bed() const;
Bed3D& get_bed(); Bed3D& get_bed();
const GLToolbar& get_view_toolbar() const; const GLToolbar& get_view_toolbar() const;
GLToolbar& get_view_toolbar(); GLToolbar& get_view_toolbar();
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
const Mouse3DController& get_mouse3d_controller() const; const Mouse3DController& get_mouse3d_controller() const;
Mouse3DController& get_mouse3d_controller(); Mouse3DController& get_mouse3d_controller();

View File

@ -147,6 +147,13 @@ void PreferencesDialog::build()
} }
}; };
def.label = L("Show the button for the collapse sidebar");
def.type = coBool;
def.tooltip = L("If enabled, the button for the collapse sidebar will be appeared in top right corner of the 3D Scene");
def.set_default_value(new ConfigOptionBool{ app_config->get("show_collapse_button") == "1" });
option = Option(def, "show_collapse_button");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Use custom size for toolbar icons"); def.label = L("Use custom size for toolbar icons");
def.type = coBool; def.type = coBool;
def.tooltip = L("If enabled, you can change size of toolbar icons manually."); def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
@ -157,6 +164,8 @@ void PreferencesDialog::build()
create_icon_size_slider(); create_icon_size_slider();
m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1"); m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1");
create_settings_mode_widget();
auto sizer = new wxBoxSizer(wxVERTICAL); auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
sizer->Add(m_optgroup_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); sizer->Add(m_optgroup_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
@ -167,7 +176,7 @@ void PreferencesDialog::build()
auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL); auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this)); wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); }); btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { accept(); });
sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5);
SetSizer(sizer); SetSizer(sizer);
sizer->SetSizeHints(this); sizer->SetSizeHints(this);
@ -179,17 +188,45 @@ void PreferencesDialog::accept()
warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME)); warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME));
} }
auto app_config = get_app_config(); auto app_config = get_app_config();
for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it) {
app_config->set(it->first, it->second); m_settings_layout_changed = m_values.find("old_settings_layout_mode") != m_values.end() ||
m_values.find("new_settings_layout_mode") != m_values.end() ||
m_values.find("dlg_settings_layout_mode") != m_values.end();
if (m_settings_layout_changed) {
// the dialog needs to be destroyed before the call to recreate_gui()
// or sometimes the application crashes into wxDialogBase() destructor
// so we put it into an inner scope
wxMessageDialog dialog(nullptr,
_L("Switching the settings layout mode will trigger application restart.\n"
"You will lose content of the plater.") + "\n\n" +
_L("Do you want to proceed?"),
wxString(SLIC3R_APP_NAME) + " - " + _L("Switching the settings layout mode"),
wxICON_QUESTION | wxOK | wxCANCEL);
if (dialog.ShowModal() == wxID_CANCEL)
{
int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 :
app_config->get("new_settings_layout_mode") == "1" ? 1 :
app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0;
m_layout_mode_box->SetSelection(selection);
return;
}
} }
app_config->save(); for (std::map<std::string, std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
app_config->set(it->first, it->second);
app_config->save();
EndModal(wxID_OK); EndModal(wxID_OK);
// Nothify the UI to update itself from the ini file. if (m_settings_layout_changed)
wxGetApp().update_ui_from_settings(); ;// application will be recreated after Preference dialog will be destroyed
else
// Nothify the UI to update itself from the ini file.
wxGetApp().update_ui_from_settings();
} }
void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect) void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect)
@ -272,6 +309,38 @@ void PreferencesDialog::create_icon_size_slider()
m_optgroup_gui->sizer->Add(m_icon_size_sizer, 0, wxEXPAND | wxALL, em); m_optgroup_gui->sizer->Add(m_icon_size_sizer, 0, wxEXPAND | wxALL, em);
} }
void PreferencesDialog::create_settings_mode_widget()
{
wxString choices[] = { _L("Old regular layout with tab bar"),
_L("New layout without the tab bar on the platter"),
_L("Settings will be shown in non-modal dialog") };
auto app_config = get_app_config();
int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 :
app_config->get("new_settings_layout_mode") == "1" ? 1 :
app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0;
wxWindow* parent = m_optgroup_gui->ctrl_parent();
m_layout_mode_box = new wxRadioBox(parent, wxID_ANY, _L("Settings layout mode"), wxDefaultPosition, wxDefaultSize, WXSIZEOF(choices), choices,
3, wxRA_SPECIFY_ROWS);
m_layout_mode_box->SetFont(wxGetApp().normal_font());
m_layout_mode_box->SetSelection(selection);
m_layout_mode_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) {
int selection = e.GetSelection();
m_values["old_settings_layout_mode"] = boost::any_cast<bool>(selection == 0) ? "1" : "0";
m_values["new_settings_layout_mode"] = boost::any_cast<bool>(selection == 1) ? "1" : "0";
m_values["dlg_settings_layout_mode"] = boost::any_cast<bool>(selection == 2) ? "1" : "0";
});
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_layout_mode_box, 1, wxALIGN_CENTER_VERTICAL);
m_optgroup_gui->sizer->Add(sizer, 0, wxEXPAND);
}
} // GUI } // GUI
} // Slic3r } // Slic3r

View File

@ -7,6 +7,8 @@
#include <wx/dialog.h> #include <wx/dialog.h>
#include <map> #include <map>
class wxRadioBox;
namespace Slic3r { namespace Slic3r {
namespace GUI { namespace GUI {
@ -19,11 +21,15 @@ class PreferencesDialog : public DPIDialog
std::shared_ptr<ConfigOptionsGroup> m_optgroup_camera; std::shared_ptr<ConfigOptionsGroup> m_optgroup_camera;
std::shared_ptr<ConfigOptionsGroup> m_optgroup_gui; std::shared_ptr<ConfigOptionsGroup> m_optgroup_gui;
wxSizer* m_icon_size_sizer; wxSizer* m_icon_size_sizer;
wxRadioBox* m_layout_mode_box;
bool isOSX {false}; bool isOSX {false};
bool m_settings_layout_changed {false};
public: public:
PreferencesDialog(wxWindow* parent); PreferencesDialog(wxWindow* parent);
~PreferencesDialog() {} ~PreferencesDialog() {}
bool settings_layout_changed() { return m_settings_layout_changed; }
void build(); void build();
void accept(); void accept();
@ -31,6 +37,7 @@ protected:
void on_dpi_changed(const wxRect &suggested_rect) override; void on_dpi_changed(const wxRect &suggested_rect) override;
void layout(); void layout();
void create_icon_size_slider(); void create_icon_size_slider();
void create_settings_mode_widget();
}; };
} // GUI } // GUI

View File

@ -39,6 +39,23 @@ static const std::vector<std::wstring>& NameByType()
return data; return data;
} }
static char marker_by_type(Preset::Type type, PrinterTechnology pt)
{
switch(type) {
case Preset::TYPE_PRINT:
case Preset::TYPE_SLA_PRINT:
return ImGui::PrintIconMarker;
case Preset::TYPE_FILAMENT:
return ImGui::FilamentIconMarker;
case Preset::TYPE_SLA_MATERIAL:
return ImGui::MaterialIconMarker;
case Preset::TYPE_PRINTER:
return pt == ptSLA ? ImGui::PrinterSlaIconMarker : ImGui::PrinterIconMarker;
default:
return ' ';
}
}
void FoundOption::get_marked_label_and_tooltip(const char** label_, const char** tooltip_) const void FoundOption::get_marked_label_and_tooltip(const char** label_, const char** tooltip_) const
{ {
*label_ = marked_label.c_str(); *label_ = marked_label.c_str();
@ -106,17 +123,8 @@ void OptionsSearcher::append_options(DynamicPrintConfig* config, Preset::Type ty
emplace(opt_key, label); emplace(opt_key, label);
else else
for (int i = 0; i < cnt; ++i) for (int i = 0; i < cnt; ++i)
emplace(opt_key + "[" + std::to_string(i) + "]", label); // ! It's very important to use "#". opt_key#n is a real option key used in GroupAndCategory
emplace(opt_key + "#" + std::to_string(i), label);
/*const GroupAndCategory& gc = groups_and_categories[opt_key];
if (gc.group.IsEmpty() || gc.category.IsEmpty())
continue;
if (!label.IsEmpty())
options.emplace_back(Option{opt_key, type,
label, _(label),
gc.group, _(gc.group),
gc.category, _(gc.category) });*/
} }
} }
@ -183,19 +191,19 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
bool full_list = search.empty(); bool full_list = search.empty();
std::wstring sep = L" : "; std::wstring sep = L" : ";
const std::vector<std::wstring>& name_by_type = NameByType();
auto get_label = [this, &name_by_type, &sep](const Option& opt) auto get_label = [this, &sep](const Option& opt)
{ {
std::wstring out; std::wstring out;
out += marker_by_type(opt.type, printer_technology);
const std::wstring *prev = nullptr; const std::wstring *prev = nullptr;
for (const std::wstring * const s : { for (const std::wstring * const s : {
view_params.type ? &(name_by_type[opt.type]) : nullptr,
view_params.category ? &opt.category_local : nullptr, view_params.category ? &opt.category_local : nullptr,
view_params.group ? &opt.group_local : nullptr, view_params.group ? &opt.group_local : nullptr,
&opt.label_local }) &opt.label_local })
if (s != nullptr && (prev == nullptr || *prev != *s)) { if (s != nullptr && (prev == nullptr || *prev != *s)) {
if (! out.empty()) // if (! out.empty())
if (out.size()>2)
out += sep; out += sep;
out += *s; out += *s;
prev = s; prev = s;
@ -203,17 +211,18 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
return out; return out;
}; };
auto get_label_english = [this, &name_by_type, &sep](const Option& opt) auto get_label_english = [this, &sep](const Option& opt)
{ {
std::wstring out; std::wstring out;
out += marker_by_type(opt.type, printer_technology);
const std::wstring*prev = nullptr; const std::wstring*prev = nullptr;
for (const std::wstring * const s : { for (const std::wstring * const s : {
view_params.type ? &name_by_type[opt.type] : nullptr,
view_params.category ? &opt.category : nullptr, view_params.category ? &opt.category : nullptr,
view_params.group ? &opt.group : nullptr, view_params.group ? &opt.group : nullptr,
&opt.label }) &opt.label })
if (s != nullptr && (prev == nullptr || *prev != *s)) { if (s != nullptr && (prev == nullptr || *prev != *s)) {
if (! out.empty()) // if (! out.empty())
if (out.size()>2)
out += sep; out += sep;
out += *s; out += *s;
prev = s; prev = s;
@ -221,9 +230,9 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
return out; return out;
}; };
auto get_tooltip = [this, &name_by_type, &sep](const Option& opt) auto get_tooltip = [this, &sep](const Option& opt)
{ {
return name_by_type[opt.type] + sep + return marker_by_type(opt.type, printer_technology) +
opt.category_local + sep + opt.category_local + sep +
opt.group_local + sep + opt.label_local; opt.group_local + sep + opt.label_local;
}; };
@ -423,15 +432,17 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
wxBoxSizer* check_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* check_sizer = new wxBoxSizer(wxHORIZONTAL);
check_type = new wxCheckBox(this, wxID_ANY, _L("Type"));
check_category = new wxCheckBox(this, wxID_ANY, _L("Category")); check_category = new wxCheckBox(this, wxID_ANY, _L("Category"));
check_group = new wxCheckBox(this, wxID_ANY, _L("Group")); check_group = new wxCheckBox(this, wxID_ANY, _L("Group"));
if (GUI::wxGetApp().is_localized())
check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English"));
wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL); wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
check_sizer->Add(check_type, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->Add(check_group, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(check_group, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
if (GUI::wxGetApp().is_localized())
check_sizer->Add(check_english, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->AddStretchSpacer(border); check_sizer->AddStretchSpacer(border);
check_sizer->Add(cancel_btn, 0, wxALIGN_CENTER_VERTICAL); check_sizer->Add(cancel_btn, 0, wxALIGN_CENTER_VERTICAL);
@ -450,7 +461,8 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
search_list->Bind(wxEVT_LEFT_UP, &SearchDialog::OnMouseClick, this); search_list->Bind(wxEVT_LEFT_UP, &SearchDialog::OnMouseClick, this);
search_list->Bind(wxEVT_KEY_DOWN,&SearchDialog::OnKeyDown, this); search_list->Bind(wxEVT_KEY_DOWN,&SearchDialog::OnKeyDown, this);
check_type ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this); if (GUI::wxGetApp().is_localized())
check_english ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this); check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
check_group ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this); check_group ->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
@ -470,9 +482,9 @@ void SearchDialog::Popup(wxPoint position /*= wxDefaultPosition*/)
update_list(); update_list();
const OptionViewParameters& params = searcher->view_params; const OptionViewParameters& params = searcher->view_params;
check_type->SetValue(params.type);
check_category->SetValue(params.category); check_category->SetValue(params.category);
check_group->SetValue(params.group); check_group->SetValue(params.group);
check_english->SetValue(params.english);
this->SetPosition(position); this->SetPosition(position);
this->ShowModal(); this->ShowModal();
@ -538,7 +550,7 @@ void SearchDialog::update_list()
const std::vector<FoundOption>& filters = searcher->found_options(); const std::vector<FoundOption>& filters = searcher->found_options();
for (const FoundOption& item : filters) for (const FoundOption& item : filters)
search_list->Append(from_u8(item.label)); search_list->Append(from_u8(item.label).Remove(0, 1));
} }
void SearchDialog::OnKeyDown(wxKeyEvent& event) void SearchDialog::OnKeyDown(wxKeyEvent& event)
@ -570,7 +582,7 @@ void SearchDialog::OnKeyDown(wxKeyEvent& event)
void SearchDialog::OnCheck(wxCommandEvent& event) void SearchDialog::OnCheck(wxCommandEvent& event)
{ {
OptionViewParameters& params = searcher->view_params; OptionViewParameters& params = searcher->view_params;
params.type = check_type->GetValue(); params.english = check_english->GetValue();
params.category = check_category->GetValue(); params.category = check_category->GetValue();
params.group = check_group->GetValue(); params.group = check_group->GetValue();

View File

@ -66,17 +66,18 @@ struct FoundOption {
struct OptionViewParameters struct OptionViewParameters
{ {
bool type {false};
bool category {false}; bool category {false};
bool group {true }; bool group {true };
bool english {false};
int hovered_id {-1}; int hovered_id {0};
}; };
class OptionsSearcher class OptionsSearcher
{ {
std::string search_line; std::string search_line;
std::map<std::string, GroupAndCategory> groups_and_categories; std::map<std::string, GroupAndCategory> groups_and_categories;
PrinterTechnology printer_technology;
std::vector<Option> options {}; std::vector<Option> options {};
std::vector<FoundOption> found {}; std::vector<FoundOption> found {};
@ -120,6 +121,8 @@ public:
const std::vector<FoundOption>& found_options() { return found; } const std::vector<FoundOption>& found_options() { return found; }
const GroupAndCategory& get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; } const GroupAndCategory& get_group_and_category (const std::string& opt_key) { return groups_and_categories[opt_key]; }
std::string& search_string() { return search_line; } std::string& search_string() { return search_line; }
void set_printer_technology(PrinterTechnology pt) { printer_technology = pt; }
}; };
@ -167,9 +170,9 @@ class SearchDialog : public GUI::DPIDialog
wxTextCtrl* search_line { nullptr }; wxTextCtrl* search_line { nullptr };
wxListBox* search_list { nullptr }; wxListBox* search_list { nullptr };
wxCheckBox* check_type { nullptr };
wxCheckBox* check_category { nullptr }; wxCheckBox* check_category { nullptr };
wxCheckBox* check_group { nullptr }; wxCheckBox* check_group { nullptr };
wxCheckBox* check_english { nullptr };
OptionsSearcher* searcher; OptionsSearcher* searcher;

View File

@ -440,11 +440,9 @@ void Selection::clear()
update_type(); update_type();
this->set_bounding_boxes_dirty(); this->set_bounding_boxes_dirty();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
// this happens while the application is closing // this happens while the application is closing
if (wxGetApp().obj_manipul() == nullptr) if (wxGetApp().obj_manipul() == nullptr)
return; return;
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
// resets the cache in the sidebar // resets the cache in the sidebar
wxGetApp().obj_manipul()->reset_cache(); wxGetApp().obj_manipul()->reset_cache();

View File

@ -145,11 +145,7 @@ SysInfoDialog::SysInfoDialog()
"</font>" "</font>"
"</body>" "</body>"
"</html>", bgr_clr_str, text_clr_str, text_clr_str, "</html>", bgr_clr_str, text_clr_str, text_clr_str,
#if ENABLE_NON_STATIC_CANVAS_MANAGER
get_mem_info(true) + "<br>" + wxGetApp().get_gl_info(true, true)); get_mem_info(true) + "<br>" + wxGetApp().get_gl_info(true, true));
#else
get_mem_info(true) + "<br>" + _3DScene::get_gl_info(true, true));
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
m_opengl_info_html->SetPage(text); m_opengl_info_html->SetPage(text);
main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15); main_sizer->Add(m_opengl_info_html, 1, wxEXPAND | wxBOTTOM, 15);
} }
@ -202,11 +198,7 @@ void SysInfoDialog::on_dpi_changed(const wxRect &suggested_rect)
void SysInfoDialog::onCopyToClipboard(wxEvent &) void SysInfoDialog::onCopyToClipboard(wxEvent &)
{ {
wxTheClipboard->Open(); wxTheClipboard->Open();
#if ENABLE_NON_STATIC_CANVAS_MANAGER
const auto text = get_main_info(false) + "\n" + wxGetApp().get_gl_info(false, true); const auto text = get_main_info(false) + "\n" + wxGetApp().get_gl_info(false, true);
#else
const auto text = get_main_info(false)+"\n"+_3DScene::get_gl_info(false, true);
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
wxTheClipboard->SetData(new wxTextDataObject(text)); wxTheClipboard->SetData(new wxTextDataObject(text));
wxTheClipboard->Close(); wxTheClipboard->Close();
} }