Fixed conflicts after merge with master
This commit is contained in:
commit
29cbfa7c9e
45 changed files with 1404 additions and 234 deletions
|
@ -1,6 +1,21 @@
|
||||||
#version 110
|
#version 110
|
||||||
|
|
||||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||||
|
const vec3 GREEN = vec3(0.0, 0.7, 0.0);
|
||||||
|
const vec3 YELLOW = vec3(0.5, 0.7, 0.0);
|
||||||
|
const vec3 RED = vec3(0.7, 0.0, 0.0);
|
||||||
|
const float EPSILON = 0.0001;
|
||||||
|
|
||||||
|
struct SlopeDetection
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
// x = yellow, y = red
|
||||||
|
vec2 z_range;
|
||||||
|
mat3 volume_world_normal_matrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform vec4 uniform_color;
|
||||||
|
uniform SlopeDetection slope;
|
||||||
|
|
||||||
varying vec3 clipping_planes_dots;
|
varying vec3 clipping_planes_dots;
|
||||||
|
|
||||||
|
@ -10,14 +25,20 @@ varying vec2 intensity;
|
||||||
varying vec3 delta_box_min;
|
varying vec3 delta_box_min;
|
||||||
varying vec3 delta_box_max;
|
varying vec3 delta_box_max;
|
||||||
|
|
||||||
uniform vec4 uniform_color;
|
varying float world_normal_z;
|
||||||
|
|
||||||
|
vec3 slope_color()
|
||||||
|
{
|
||||||
|
float gradient_range = slope.z_range.x - slope.z_range.y;
|
||||||
|
return (world_normal_z > slope.z_range.x - EPSILON) ? GREEN : ((gradient_range == 0.0) ? RED : mix(RED, YELLOW, clamp((world_normal_z - slope.z_range.y) / gradient_range, 0.0, 1.0)));
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
if (any(lessThan(clipping_planes_dots, ZERO)))
|
if (any(lessThan(clipping_planes_dots, ZERO)))
|
||||||
discard;
|
discard;
|
||||||
|
vec3 color = slope.active ? slope_color() : uniform_color.rgb;
|
||||||
// if the fragment is outside the print volume -> use darker color
|
// if the fragment is outside the print volume -> use darker color
|
||||||
vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb;
|
color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
|
||||||
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
|
gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,13 +20,22 @@ const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
struct PrintBoxDetection
|
struct PrintBoxDetection
|
||||||
{
|
{
|
||||||
|
bool active;
|
||||||
vec3 min;
|
vec3 min;
|
||||||
vec3 max;
|
vec3 max;
|
||||||
bool volume_detection;
|
|
||||||
mat4 volume_world_matrix;
|
mat4 volume_world_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SlopeDetection
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
// x = yellow, y = red
|
||||||
|
vec2 z_range;
|
||||||
|
mat3 volume_world_normal_matrix;
|
||||||
|
};
|
||||||
|
|
||||||
uniform PrintBoxDetection print_box;
|
uniform PrintBoxDetection print_box;
|
||||||
|
uniform SlopeDetection slope;
|
||||||
|
|
||||||
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
|
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
|
||||||
uniform vec2 z_range;
|
uniform vec2 z_range;
|
||||||
|
@ -41,6 +50,8 @@ varying vec3 delta_box_max;
|
||||||
|
|
||||||
varying vec3 clipping_planes_dots;
|
varying vec3 clipping_planes_dots;
|
||||||
|
|
||||||
|
varying float world_normal_z;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// First transform the normal into camera space and normalize the result.
|
// First transform the normal into camera space and normalize the result.
|
||||||
|
@ -61,7 +72,7 @@ void main()
|
||||||
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
|
||||||
|
|
||||||
// compute deltas for out of print volume detection (world coordinates)
|
// compute deltas for out of print volume detection (world coordinates)
|
||||||
if (print_box.volume_detection)
|
if (print_box.active)
|
||||||
{
|
{
|
||||||
vec3 v = (print_box.volume_world_matrix * gl_Vertex).xyz;
|
vec3 v = (print_box.volume_world_matrix * gl_Vertex).xyz;
|
||||||
delta_box_min = v - print_box.min;
|
delta_box_min = v - print_box.min;
|
||||||
|
@ -73,6 +84,9 @@ void main()
|
||||||
delta_box_max = ZERO;
|
delta_box_max = ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// z component of normal vector in world coordinate used for slope shading
|
||||||
|
world_normal_z = slope.active ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
|
||||||
|
|
||||||
gl_Position = ftransform();
|
gl_Position = ftransform();
|
||||||
// Point in homogenous coordinates.
|
// Point in homogenous coordinates.
|
||||||
vec4 world_pos = print_box.volume_world_matrix * gl_Vertex;
|
vec4 world_pos = print_box.volume_world_matrix * gl_Vertex;
|
||||||
|
|
|
@ -535,8 +535,10 @@ 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.
|
//FIXME this is a workaround for the PrusaSlicer 2.1 release.
|
||||||
_3DScene::destroy();
|
_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.
|
||||||
|
|
|
@ -464,7 +464,7 @@ bool ConfigBase::set_deserialize_nothrow(const t_config_option_key &opt_key_src,
|
||||||
void ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append)
|
void ConfigBase::set_deserialize(const t_config_option_key &opt_key_src, const std::string &value_src, bool append)
|
||||||
{
|
{
|
||||||
if (! this->set_deserialize_nothrow(opt_key_src, value_src, append))
|
if (! this->set_deserialize_nothrow(opt_key_src, value_src, append))
|
||||||
throw BadOptionTypeException("ConfigBase::set_deserialize() failed");
|
throw BadOptionTypeException((boost::format("ConfigBase::set_deserialize() failed for parameter \"%1%\", value \"%2%\"") % opt_key_src % value_src).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigBase::set_deserialize(std::initializer_list<SetDeserializeItem> items)
|
void ConfigBase::set_deserialize(std::initializer_list<SetDeserializeItem> items)
|
||||||
|
|
|
@ -56,10 +56,9 @@ public:
|
||||||
class BadOptionTypeException : public std::runtime_error
|
class BadOptionTypeException : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BadOptionTypeException() :
|
BadOptionTypeException() : std::runtime_error("Bad option type exception") {}
|
||||||
std::runtime_error("Bad option type exception") {}
|
BadOptionTypeException(const std::string &message) : std::runtime_error(message) {}
|
||||||
BadOptionTypeException(const char* message) :
|
BadOptionTypeException(const char* message) : std::runtime_error(message) {}
|
||||||
std::runtime_error(message) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type of a configuration value.
|
// Type of a configuration value.
|
||||||
|
|
|
@ -218,10 +218,10 @@ public:
|
||||||
bbox.min /= m_resolution;
|
bbox.min /= m_resolution;
|
||||||
bbox.max /= m_resolution;
|
bbox.max /= m_resolution;
|
||||||
// Trim with the cells.
|
// Trim with the cells.
|
||||||
bbox.min.x() = std::max(bbox.min.x(), 0);
|
bbox.min.x() = std::max<coord_t>(bbox.min.x(), 0);
|
||||||
bbox.min.y() = std::max(bbox.min.y(), 0);
|
bbox.min.y() = std::max<coord_t>(bbox.min.y(), 0);
|
||||||
bbox.max.x() = std::min(bbox.max.x(), (coord_t)m_cols - 1);
|
bbox.max.x() = std::min<coord_t>(bbox.max.x(), (coord_t)m_cols - 1);
|
||||||
bbox.max.y() = std::min(bbox.max.y(), (coord_t)m_rows - 1);
|
bbox.max.y() = std::min<coord_t>(bbox.max.y(), (coord_t)m_rows - 1);
|
||||||
for (coord_t iy = bbox.min.y(); iy <= bbox.max.y(); ++ iy)
|
for (coord_t iy = bbox.min.y(); iy <= bbox.max.y(); ++ iy)
|
||||||
for (coord_t ix = bbox.min.x(); ix <= bbox.max.x(); ++ ix)
|
for (coord_t ix = bbox.min.x(); ix <= bbox.max.x(); ++ ix)
|
||||||
if (! visitor(iy, ix))
|
if (! visitor(iy, ix))
|
||||||
|
|
|
@ -94,7 +94,7 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
|
||||||
// Reorder the extruders to minimize tool switches.
|
// Reorder the extruders to minimize tool switches.
|
||||||
this->reorder_extruders(first_extruder);
|
this->reorder_extruders(first_extruder);
|
||||||
|
|
||||||
this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height);
|
this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, object.config().layer_height);
|
||||||
|
|
||||||
this->collect_extruder_statistics(prime_multi_material);
|
this->collect_extruder_statistics(prime_multi_material);
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
|
||||||
|
|
||||||
// Initialize the print layers for all objects and all layers.
|
// Initialize the print layers for all objects and all layers.
|
||||||
coordf_t object_bottom_z = 0.;
|
coordf_t object_bottom_z = 0.;
|
||||||
|
coordf_t max_layer_height = 0.;
|
||||||
{
|
{
|
||||||
std::vector<coordf_t> zs;
|
std::vector<coordf_t> zs;
|
||||||
for (auto object : print.objects()) {
|
for (auto object : print.objects()) {
|
||||||
|
@ -122,6 +123,8 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
|
||||||
object_bottom_z = layer->print_z - layer->height;
|
object_bottom_z = layer->print_z - layer->height;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
max_layer_height = std::max(max_layer_height, object->config().layer_height.value);
|
||||||
}
|
}
|
||||||
this->initialize_layers(zs);
|
this->initialize_layers(zs);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +147,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
|
||||||
// Reorder the extruders to minimize tool switches.
|
// Reorder the extruders to minimize tool switches.
|
||||||
this->reorder_extruders(first_extruder);
|
this->reorder_extruders(first_extruder);
|
||||||
|
|
||||||
this->fill_wipe_tower_partitions(print.config(), object_bottom_z);
|
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
|
||||||
|
|
||||||
this->collect_extruder_statistics(prime_multi_material);
|
this->collect_extruder_statistics(prime_multi_material);
|
||||||
}
|
}
|
||||||
|
@ -318,7 +321,7 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z)
|
void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_object_layer_height)
|
||||||
{
|
{
|
||||||
if (m_layer_tools.empty())
|
if (m_layer_tools.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -351,6 +354,10 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
|
||||||
mlh = 0.75 * config.nozzle_diameter.values[i];
|
mlh = 0.75 * config.nozzle_diameter.values[i];
|
||||||
max_layer_height = std::min(max_layer_height, mlh);
|
max_layer_height = std::min(max_layer_height, mlh);
|
||||||
}
|
}
|
||||||
|
// The Prusa3D Fast (0.35mm layer height) print profile sets a higher layer height than what is normally allowed
|
||||||
|
// by the nozzle. This is a hack and it works by increasing extrusion width.
|
||||||
|
max_layer_height = std::max(max_layer_height, max_object_layer_height);
|
||||||
|
|
||||||
for (size_t i = 0; i + 1 < m_layer_tools.size(); ++ i) {
|
for (size_t i = 0; i + 1 < m_layer_tools.size(); ++ i) {
|
||||||
const LayerTools < = m_layer_tools[i];
|
const LayerTools < = m_layer_tools[i];
|
||||||
const LayerTools <_next = m_layer_tools[i + 1];
|
const LayerTools <_next = m_layer_tools[i + 1];
|
||||||
|
@ -393,21 +400,47 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_
|
||||||
// and maybe other problems. We will therefore go through layer_tools and detect and fix this.
|
// and maybe other problems. We will therefore go through layer_tools and detect and fix this.
|
||||||
// So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder),
|
// So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder),
|
||||||
// we'll mark it with has_wipe tower.
|
// we'll mark it with has_wipe tower.
|
||||||
for (unsigned int i=0; i+1<m_layer_tools.size(); ++i) {
|
assert(! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower);
|
||||||
LayerTools& lt = m_layer_tools[i];
|
if (! m_layer_tools.empty() && m_layer_tools.front().has_wipe_tower) {
|
||||||
LayerTools& lt_next = m_layer_tools[i+1];
|
for (size_t i = 0; i + 1 < m_layer_tools.size();) {
|
||||||
if (lt.extruders.empty() || lt_next.extruders.empty())
|
const LayerTools < = m_layer_tools[i];
|
||||||
break;
|
assert(lt.has_wipe_tower);
|
||||||
if (!lt_next.has_wipe_tower && (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1))
|
assert(! lt.extruders.empty());
|
||||||
lt_next.has_wipe_tower = true;
|
// Find the next layer with wipe tower or mark a layer as such.
|
||||||
// We should also check that the next wipe tower layer is no further than max_layer_height:
|
size_t j = i + 1;
|
||||||
unsigned int j = i+1;
|
for (; j < m_layer_tools.size() && ! m_layer_tools[j].has_wipe_tower; ++ j) {
|
||||||
double last_wipe_tower_print_z = lt_next.print_z;
|
LayerTools <_next = m_layer_tools[j];
|
||||||
while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower)
|
if (lt_next.extruders.empty()) {
|
||||||
if (m_layer_tools[j+1].print_z - last_wipe_tower_print_z > max_layer_height) {
|
//FIXME Vojtech: Lukasi, proc?
|
||||||
m_layer_tools[j].has_wipe_tower = true;
|
j = m_layer_tools.size();
|
||||||
last_wipe_tower_print_z = m_layer_tools[j].print_z;
|
break;
|
||||||
|
}
|
||||||
|
if (lt_next.extruders.front() != lt.extruders.back() || lt_next.extruders.size() > 1) {
|
||||||
|
// Support only layer, soluble layers? Otherwise the layer should have been already marked as having wipe tower.
|
||||||
|
assert(lt_next.has_support && ! lt_next.has_object);
|
||||||
|
lt_next.has_wipe_tower = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (j == m_layer_tools.size())
|
||||||
|
// No wipe tower above layer i, therefore no need to add any wipe tower layer above i.
|
||||||
|
break;
|
||||||
|
// We should also check that the next wipe tower layer is no further than max_layer_height.
|
||||||
|
// This algorith may in theory create very thin wipe layer j if layer closely below j is marked as wipe tower.
|
||||||
|
// This may happen if printing with non-soluble break away supports.
|
||||||
|
// On the other side it should not hurt as there will be no wipe, just perimeter and sparse infill printed
|
||||||
|
// at that particular wipe tower layer without extruder change.
|
||||||
|
double last_wipe_tower_print_z = lt.print_z;
|
||||||
|
assert(m_layer_tools[j].has_wipe_tower);
|
||||||
|
for (size_t k = i + 1; k < j; ++k) {
|
||||||
|
assert(! m_layer_tools[k].has_wipe_tower);
|
||||||
|
if (m_layer_tools[k + 1].print_z - last_wipe_tower_print_z > max_layer_height + EPSILON) {
|
||||||
|
m_layer_tools[k].has_wipe_tower = true;
|
||||||
|
last_wipe_tower_print_z = m_layer_tools[k].print_z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the wipe_tower_layer_height values.
|
// Calculate the wipe_tower_layer_height values.
|
||||||
|
|
|
@ -166,7 +166,7 @@ private:
|
||||||
void initialize_layers(std::vector<coordf_t> &zs);
|
void initialize_layers(std::vector<coordf_t> &zs);
|
||||||
void collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
|
void collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
|
||||||
void reorder_extruders(unsigned int last_extruder_id);
|
void reorder_extruders(unsigned int last_extruder_id);
|
||||||
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z);
|
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
|
||||||
void collect_extruder_statistics(bool prime_multi_material);
|
void collect_extruder_statistics(bool prime_multi_material);
|
||||||
|
|
||||||
std::vector<LayerTools> m_layer_tools;
|
std::vector<LayerTools> m_layer_tools;
|
||||||
|
|
|
@ -29,7 +29,7 @@ TriangleMesh eigen_to_triangle_mesh(const EigenMesh &emesh)
|
||||||
auto &VC = emesh.first; auto &FC = emesh.second;
|
auto &VC = emesh.first; auto &FC = emesh.second;
|
||||||
|
|
||||||
Pointf3s points(size_t(VC.rows()));
|
Pointf3s points(size_t(VC.rows()));
|
||||||
std::vector<Vec3crd> facets(size_t(FC.rows()));
|
std::vector<Vec3i> facets(size_t(FC.rows()));
|
||||||
|
|
||||||
for (Eigen::Index i = 0; i < VC.rows(); ++i)
|
for (Eigen::Index i = 0; i < VC.rows(); ++i)
|
||||||
points[size_t(i)] = VC.row(i);
|
points[size_t(i)] = VC.row(i);
|
||||||
|
@ -154,7 +154,7 @@ inline Vec3d to_vec3d(const _EpecMesh::Point &v)
|
||||||
template<class _Mesh> TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh)
|
template<class _Mesh> TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh)
|
||||||
{
|
{
|
||||||
Pointf3s points;
|
Pointf3s points;
|
||||||
std::vector<Vec3crd> facets;
|
std::vector<Vec3i> facets;
|
||||||
points.reserve(cgalmesh.num_vertices());
|
points.reserve(cgalmesh.num_vertices());
|
||||||
facets.reserve(cgalmesh.num_faces());
|
facets.reserve(cgalmesh.num_faces());
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ template<class _Mesh> TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh)
|
||||||
for (auto &face : cgalmesh.faces()) {
|
for (auto &face : cgalmesh.faces()) {
|
||||||
auto vtc = cgalmesh.vertices_around_face(cgalmesh.halfedge(face));
|
auto vtc = cgalmesh.vertices_around_face(cgalmesh.halfedge(face));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Vec3crd trface;
|
Vec3i trface;
|
||||||
for (auto v : vtc) trface(i++) = static_cast<int>(v);
|
for (auto v : vtc) trface(i++) = static_cast<int>(v);
|
||||||
facets.emplace_back(trface);
|
facets.emplace_back(trface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
|
||||||
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
|
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
|
||||||
typedef Eigen::Matrix<int, 2, 1, Eigen::DontAlign> Vec2i;
|
typedef Eigen::Matrix<int, 2, 1, Eigen::DontAlign> Vec2i;
|
||||||
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> Vec3i;
|
typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> Vec3i;
|
||||||
|
typedef Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign> Vec2i32;
|
||||||
typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
|
typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
|
||||||
|
typedef Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign> Vec3i32;
|
||||||
typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
|
typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
|
||||||
|
|
||||||
// Vector types with a double coordinate base type.
|
// Vector types with a double coordinate base type.
|
||||||
|
@ -53,12 +55,12 @@ typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d
|
||||||
|
|
||||||
inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
|
inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
|
||||||
|
|
||||||
|
inline int32_t cross2(const Vec2i32 &v1, const Vec2i32 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
||||||
inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
||||||
inline coord_t cross2(const Vec2crd &v1, const Vec2crd &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
|
||||||
inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
||||||
inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
|
||||||
|
|
||||||
inline Vec2crd to_2d(const Vec3crd &pt3) { return Vec2crd(pt3(0), pt3(1)); }
|
inline Vec2i32 to_2d(const Vec2i32 &pt3) { return Vec2i32(pt3(0), pt3(1)); }
|
||||||
inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); }
|
inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); }
|
||||||
inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); }
|
inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); }
|
||||||
inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); }
|
inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); }
|
||||||
|
@ -89,8 +91,8 @@ public:
|
||||||
typedef coord_t coord_type;
|
typedef coord_t coord_type;
|
||||||
|
|
||||||
Point() : Vec2crd(0, 0) {}
|
Point() : Vec2crd(0, 0) {}
|
||||||
Point(coord_t x, coord_t y) : Vec2crd(x, y) {}
|
Point(int32_t x, int32_t y) : Vec2crd(coord_t(x), coord_t(y)) {}
|
||||||
Point(int64_t x, int64_t y) : Vec2crd(coord_t(x), coord_t(y)) {} // for Clipper
|
Point(int64_t x, int64_t y) : Vec2crd(coord_t(x), coord_t(y)) {}
|
||||||
Point(double x, double y) : Vec2crd(coord_t(lrint(x)), coord_t(lrint(y))) {}
|
Point(double x, double y) : Vec2crd(coord_t(lrint(x)), coord_t(lrint(y))) {}
|
||||||
Point(const Point &rhs) { *this = rhs; }
|
Point(const Point &rhs) { *this = rhs; }
|
||||||
explicit Point(const Vec2d& rhs) : Vec2crd(coord_t(lrint(rhs.x())), coord_t(lrint(rhs.y()))) {}
|
explicit Point(const Vec2d& rhs) : Vec2crd(coord_t(lrint(rhs.x())), coord_t(lrint(rhs.y()))) {}
|
||||||
|
|
|
@ -228,7 +228,7 @@ void to_eigen_mesh(const TriangleMesh &tmesh, Eigen::MatrixXd &V, Eigen::MatrixX
|
||||||
void to_triangle_mesh(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, TriangleMesh &out)
|
void to_triangle_mesh(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, TriangleMesh &out)
|
||||||
{
|
{
|
||||||
Pointf3s points(size_t(V.rows()));
|
Pointf3s points(size_t(V.rows()));
|
||||||
std::vector<Vec3crd> facets(size_t(F.rows()));
|
std::vector<Vec3i> facets(size_t(F.rows()));
|
||||||
|
|
||||||
for (Eigen::Index i = 0; i < V.rows(); ++i)
|
for (Eigen::Index i = 0; i < V.rows(); ++i)
|
||||||
points[size_t(i)] = V.row(i);
|
points[size_t(i)] = V.row(i);
|
||||||
|
|
|
@ -48,9 +48,8 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||||
vertices.emplace_back(Vec3d(b(0), b(1), z));
|
vertices.emplace_back(Vec3d(b(0), b(1), z));
|
||||||
|
|
||||||
if (sbegin == 0)
|
if (sbegin == 0)
|
||||||
facets.emplace_back((i == 0) ?
|
(i == 0) ? facets.emplace_back(coord_t(ring.size()), 0, 1) :
|
||||||
Vec3crd(coord_t(ring.size()), 0, 1) :
|
facets.emplace_back(id - 1, 0, id);
|
||||||
Vec3crd(id - 1, 0, id));
|
|
||||||
++id;
|
++id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +65,11 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||||
auto id_ringsize = coord_t(id - int(ring.size()));
|
auto id_ringsize = coord_t(id - int(ring.size()));
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// wrap around
|
// wrap around
|
||||||
facets.emplace_back(Vec3crd(id - 1, id,
|
facets.emplace_back(id - 1, id, id + coord_t(ring.size() - 1) );
|
||||||
id + coord_t(ring.size() - 1)));
|
facets.emplace_back(id - 1, id_ringsize, id);
|
||||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize, id));
|
|
||||||
} else {
|
} else {
|
||||||
facets.emplace_back(Vec3crd(id_ringsize - 1, id_ringsize, id));
|
facets.emplace_back(id_ringsize - 1, id_ringsize, id);
|
||||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize - 1, id));
|
facets.emplace_back(id - 1, id_ringsize - 1, id);
|
||||||
}
|
}
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
|
@ -85,10 +83,10 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||||
auto id_ringsize = coord_t(id - int(ring.size()));
|
auto id_ringsize = coord_t(id - int(ring.size()));
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// third vertex is on the other side of the ring.
|
// third vertex is on the other side of the ring.
|
||||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize, id));
|
facets.emplace_back(id - 1, id_ringsize, id);
|
||||||
} else {
|
} else {
|
||||||
auto ci = coord_t(id_ringsize + coord_t(i));
|
auto ci = coord_t(id_ringsize + coord_t(i));
|
||||||
facets.emplace_back(Vec3crd(ci - 1, ci, id));
|
facets.emplace_back(ci - 1, ci, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,22 @@
|
||||||
// Enable fix for dragging mouse event handling for gizmobar
|
// Enable fix for dragging mouse event handling for gizmobar
|
||||||
#define ENABLE_GIZMO_TOOLBAR_DRAGGING_FIX (1 && ENABLE_2_2_0_FINAL)
|
#define ENABLE_GIZMO_TOOLBAR_DRAGGING_FIX (1 && ENABLE_2_2_0_FINAL)
|
||||||
|
|
||||||
|
//============
|
||||||
|
// 2.3.0 techs
|
||||||
|
//============
|
||||||
|
#define ENABLE_2_3_0 1
|
||||||
|
|
||||||
|
// Enable rendering of objects colored by facets' slope
|
||||||
|
#define ENABLE_SLOPE_RENDERING (1 && ENABLE_2_3_0)
|
||||||
|
|
||||||
|
//===================
|
||||||
|
// 2.3.0.alpha1 techs
|
||||||
|
//===================
|
||||||
|
#define ENABLE_2_3_0_ALPHA1 1
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
|
||||||
//==================
|
//==================
|
||||||
// 2.3.0.alpha1 techs
|
// 2.3.0.alpha1 techs
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& facets) : repaired(false)
|
TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3i> &facets) : repaired(false)
|
||||||
{
|
{
|
||||||
stl_file &stl = this->stl;
|
stl_file &stl = this->stl;
|
||||||
stl.stats.type = inmemory;
|
stl.stats.type = inmemory;
|
||||||
|
@ -600,7 +600,7 @@ TriangleMesh TriangleMesh::convex_hull_3d() const
|
||||||
|
|
||||||
// Let's collect results:
|
// Let's collect results:
|
||||||
Pointf3s dst_vertices;
|
Pointf3s dst_vertices;
|
||||||
std::vector<Vec3crd> facets;
|
std::vector<Vec3i> facets;
|
||||||
auto facet_list = qhull.facetList().toStdVector();
|
auto facet_list = qhull.facetList().toStdVector();
|
||||||
for (const orgQhull::QhullFacet& facet : facet_list)
|
for (const orgQhull::QhullFacet& facet : facet_list)
|
||||||
{ // iterate through facets
|
{ // iterate through facets
|
||||||
|
@ -1931,22 +1931,18 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
|
||||||
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
|
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
|
||||||
TriangleMesh make_cube(double x, double y, double z)
|
TriangleMesh make_cube(double x, double y, double z)
|
||||||
{
|
{
|
||||||
Vec3d pv[8] = {
|
TriangleMesh mesh(
|
||||||
Vec3d(x, y, 0), Vec3d(x, 0, 0), Vec3d(0, 0, 0),
|
{
|
||||||
Vec3d(0, y, 0), Vec3d(x, y, z), Vec3d(0, y, z),
|
{x, y, 0}, {x, 0, 0}, {0, 0, 0},
|
||||||
Vec3d(0, 0, z), Vec3d(x, 0, z)
|
{0, y, 0}, {x, y, z}, {0, y, z},
|
||||||
};
|
{0, 0, z}, {x, 0, z}
|
||||||
Vec3crd fv[12] = {
|
},
|
||||||
Vec3crd(0, 1, 2), Vec3crd(0, 2, 3), Vec3crd(4, 5, 6),
|
{
|
||||||
Vec3crd(4, 6, 7), Vec3crd(0, 4, 7), Vec3crd(0, 7, 1),
|
{0, 1, 2}, {0, 2, 3}, {4, 5, 6},
|
||||||
Vec3crd(1, 7, 6), Vec3crd(1, 6, 2), Vec3crd(2, 6, 5),
|
{4, 6, 7}, {0, 4, 7}, {0, 7, 1},
|
||||||
Vec3crd(2, 5, 3), Vec3crd(4, 0, 3), Vec3crd(4, 3, 5)
|
{1, 7, 6}, {1, 6, 2}, {2, 6, 5},
|
||||||
};
|
{2, 5, 3}, {4, 0, 3}, {4, 3, 5}
|
||||||
|
});
|
||||||
std::vector<Vec3crd> facets(&fv[0], &fv[0]+12);
|
|
||||||
Pointf3s vertices(&pv[0], &pv[0]+8);
|
|
||||||
|
|
||||||
TriangleMesh mesh(vertices ,facets);
|
|
||||||
mesh.repair();
|
mesh.repair();
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
@ -1959,8 +1955,8 @@ TriangleMesh make_cylinder(double r, double h, double fa)
|
||||||
size_t n_steps = (size_t)ceil(2. * PI / fa);
|
size_t n_steps = (size_t)ceil(2. * PI / fa);
|
||||||
double angle_step = 2. * PI / n_steps;
|
double angle_step = 2. * PI / n_steps;
|
||||||
|
|
||||||
Pointf3s vertices;
|
Pointf3s vertices;
|
||||||
std::vector<Vec3crd> facets;
|
std::vector<Vec3i> facets;
|
||||||
vertices.reserve(2 * n_steps + 2);
|
vertices.reserve(2 * n_steps + 2);
|
||||||
facets.reserve(4 * n_steps);
|
facets.reserve(4 * n_steps);
|
||||||
|
|
||||||
|
@ -1980,17 +1976,17 @@ TriangleMesh make_cylinder(double r, double h, double fa)
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), 0.));
|
vertices.emplace_back(Vec3d(p(0), p(1), 0.));
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), h));
|
vertices.emplace_back(Vec3d(p(0), p(1), h));
|
||||||
int id = (int)vertices.size() - 1;
|
int id = (int)vertices.size() - 1;
|
||||||
facets.emplace_back(Vec3crd( 0, id - 1, id - 3)); // top
|
facets.emplace_back( 0, id - 1, id - 3); // top
|
||||||
facets.emplace_back(Vec3crd(id, 1, id - 2)); // bottom
|
facets.emplace_back(id, 1, id - 2); // bottom
|
||||||
facets.emplace_back(Vec3crd(id, id - 2, id - 3)); // upper-right of side
|
facets.emplace_back(id, id - 2, id - 3); // upper-right of side
|
||||||
facets.emplace_back(Vec3crd(id, id - 3, id - 1)); // bottom-left of side
|
facets.emplace_back(id, id - 3, id - 1); // bottom-left of side
|
||||||
}
|
}
|
||||||
// Connect the last set of vertices with the first.
|
// Connect the last set of vertices with the first.
|
||||||
int id = (int)vertices.size() - 1;
|
int id = (int)vertices.size() - 1;
|
||||||
facets.emplace_back(Vec3crd( 0, 2, id - 1));
|
facets.emplace_back( 0, 2, id - 1);
|
||||||
facets.emplace_back(Vec3crd( 3, 1, id));
|
facets.emplace_back( 3, 1, id);
|
||||||
facets.emplace_back(Vec3crd(id, 2, 3));
|
facets.emplace_back(id, 2, 3);
|
||||||
facets.emplace_back(Vec3crd(id, id - 1, 2));
|
facets.emplace_back(id, id - 1, 2);
|
||||||
|
|
||||||
TriangleMesh mesh(std::move(vertices), std::move(facets));
|
TriangleMesh mesh(std::move(vertices), std::move(facets));
|
||||||
mesh.repair();
|
mesh.repair();
|
||||||
|
@ -2025,7 +2021,7 @@ TriangleMesh make_sphere(double radius, double fa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vec3crd> facets;
|
std::vector<Vec3i> facets;
|
||||||
facets.reserve(2 * (stackCount - 1) * sectorCount);
|
facets.reserve(2 * (stackCount - 1) * sectorCount);
|
||||||
for (int i = 0; i < stackCount; ++ i) {
|
for (int i = 0; i < stackCount; ++ i) {
|
||||||
// Beginning of current stack.
|
// Beginning of current stack.
|
||||||
|
@ -2040,11 +2036,11 @@ TriangleMesh make_sphere(double radius, double fa)
|
||||||
int k2_next = k2;
|
int k2_next = k2;
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1);
|
k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1);
|
||||||
facets.emplace_back(Vec3crd(k1, k2, k1_next));
|
facets.emplace_back(k1, k2, k1_next);
|
||||||
}
|
}
|
||||||
if (i + 1 != stackCount) {
|
if (i + 1 != stackCount) {
|
||||||
k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1);
|
k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1);
|
||||||
facets.emplace_back(Vec3crd(k1_next, k2, k2_next));
|
facets.emplace_back(k1_next, k2, k2_next);
|
||||||
}
|
}
|
||||||
k1 = k1_next;
|
k1 = k1_next;
|
||||||
k2 = k2_next;
|
k2 = k2_next;
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TriangleMesh
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TriangleMesh() : repaired(false) {}
|
TriangleMesh() : repaired(false) {}
|
||||||
TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
|
TriangleMesh(const Pointf3s &points, const std::vector<Vec3i> &facets);
|
||||||
explicit TriangleMesh(const indexed_triangle_set &M);
|
explicit TriangleMesh(const indexed_triangle_set &M);
|
||||||
void clear() { this->stl.clear(); this->its.clear(); this->repaired = false; }
|
void clear() { this->stl.clear(); this->its.clear(); this->repaired = false; }
|
||||||
bool ReadSTLFile(const char* input_file) { return stl_open(&stl, input_file); }
|
bool ReadSTLFile(const char* input_file) { return stl_open(&stl, input_file); }
|
||||||
|
|
|
@ -21,7 +21,13 @@
|
||||||
#include "Technologies.hpp"
|
#include "Technologies.hpp"
|
||||||
#include "Semver.hpp"
|
#include "Semver.hpp"
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// Saves around 32% RAM after slicing step, 6.7% after G-code export (tested on PrusaSlicer 2.2.0 final).
|
||||||
typedef int32_t coord_t;
|
typedef int32_t coord_t;
|
||||||
|
#else
|
||||||
|
typedef int64_t coord_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef double coordf_t;
|
typedef double coordf_t;
|
||||||
|
|
||||||
//FIXME This epsilon value is used for many non-related purposes:
|
//FIXME This epsilon value is used for many non-related purposes:
|
||||||
|
@ -33,6 +39,7 @@ typedef double coordf_t;
|
||||||
// This scaling generates a following fixed point representation with for a 32bit integer:
|
// This scaling generates a following fixed point representation with for a 32bit integer:
|
||||||
// 0..4294mm with 1nm resolution
|
// 0..4294mm with 1nm resolution
|
||||||
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
|
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
|
||||||
|
// with int64_t we don't have to worry anymore about the size of the int.
|
||||||
#define SCALING_FACTOR 0.000001
|
#define SCALING_FACTOR 0.000001
|
||||||
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
|
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
|
||||||
#define RESOLUTION 0.0125
|
#define RESOLUTION 0.0125
|
||||||
|
|
|
@ -394,6 +394,7 @@ void GLVolume::render() const
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLE_SLOPE_RENDERING
|
||||||
void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const
|
void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const
|
||||||
{
|
{
|
||||||
if (color_id >= 0)
|
if (color_id >= 0)
|
||||||
|
@ -409,6 +410,7 @@ void GLVolume::render(int color_id, int detection_id, int worldmatrix_id) const
|
||||||
|
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); }
|
bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); }
|
||||||
bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposPad); }
|
bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposPad); }
|
||||||
|
@ -535,16 +537,16 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
||||||
// We'll now create the box with jagged edge. y-coordinates of the pre-generated model are shifted so that the front
|
// We'll now create the box with jagged edge. y-coordinates of the pre-generated model are shifted so that the front
|
||||||
// edge has y=0 and centerline of the back edge has y=depth:
|
// edge has y=0 and centerline of the back edge has y=depth:
|
||||||
Pointf3s points;
|
Pointf3s points;
|
||||||
std::vector<Vec3crd> facets;
|
std::vector<Vec3i> facets;
|
||||||
float out_points_idx[][3] = { { 0, -depth, 0 }, { 0, 0, 0 }, { 38.453f, 0, 0 }, { 61.547f, 0, 0 }, { 100.0f, 0, 0 }, { 100.0f, -depth, 0 }, { 55.7735f, -10.0f, 0 }, { 44.2265f, 10.0f, 0 },
|
float out_points_idx[][3] = { { 0, -depth, 0 }, { 0, 0, 0 }, { 38.453f, 0, 0 }, { 61.547f, 0, 0 }, { 100.0f, 0, 0 }, { 100.0f, -depth, 0 }, { 55.7735f, -10.0f, 0 }, { 44.2265f, 10.0f, 0 },
|
||||||
{ 38.453f, 0, 1 }, { 0, 0, 1 }, { 0, -depth, 1 }, { 100.0f, -depth, 1 }, { 100.0f, 0, 1 }, { 61.547f, 0, 1 }, { 55.7735f, -10.0f, 1 }, { 44.2265f, 10.0f, 1 } };
|
{ 38.453f, 0, 1 }, { 0, 0, 1 }, { 0, -depth, 1 }, { 100.0f, -depth, 1 }, { 100.0f, 0, 1 }, { 61.547f, 0, 1 }, { 55.7735f, -10.0f, 1 }, { 44.2265f, 10.0f, 1 } };
|
||||||
int out_facets_idx[][3] = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 5, 0 }, { 3, 5, 6 }, { 6, 2, 7 }, { 6, 0, 2 }, { 8, 9, 10 }, { 11, 12, 13 }, { 10, 11, 14 }, { 14, 11, 13 }, { 15, 8, 14 },
|
int out_facets_idx[][3] = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 5, 0 }, { 3, 5, 6 }, { 6, 2, 7 }, { 6, 0, 2 }, { 8, 9, 10 }, { 11, 12, 13 }, { 10, 11, 14 }, { 14, 11, 13 }, { 15, 8, 14 },
|
||||||
{8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8},
|
{8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8},
|
||||||
{0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11} };
|
{0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11} };
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
points.push_back(Vec3d(out_points_idx[i][0] / (100.f / min_width), out_points_idx[i][1] + depth, out_points_idx[i][2]));
|
points.emplace_back(out_points_idx[i][0] / (100.f / min_width), out_points_idx[i][1] + depth, out_points_idx[i][2]);
|
||||||
for (int i = 0; i < 28; ++i)
|
for (int i = 0; i < 28; ++i)
|
||||||
facets.push_back(Vec3crd(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2]));
|
facets.emplace_back(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2]);
|
||||||
TriangleMesh tooth_mesh(points, facets);
|
TriangleMesh tooth_mesh(points, facets);
|
||||||
|
|
||||||
// We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to
|
// We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to
|
||||||
|
@ -650,28 +652,64 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
||||||
GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1;
|
GLint z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "z_range") : -1;
|
||||||
GLint clipping_plane_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "clipping_plane") : -1;
|
GLint clipping_plane_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "clipping_plane") : -1;
|
||||||
|
|
||||||
GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1;
|
GLint print_box_min_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.min") : -1;
|
||||||
GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1;
|
GLint print_box_max_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.max") : -1;
|
||||||
GLint print_box_detection_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
|
GLint print_box_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.active") : -1;
|
||||||
GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
|
GLint print_box_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
GLint slope_active_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.active") : -1;
|
||||||
|
GLint slope_normal_matrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.volume_world_normal_matrix") : -1;
|
||||||
|
GLint slope_z_range_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "slope.z_range") : -1;
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
glcheck();
|
glcheck();
|
||||||
|
|
||||||
if (print_box_min_id != -1)
|
if (print_box_min_id != -1)
|
||||||
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min));
|
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)m_print_box_min));
|
||||||
|
|
||||||
if (print_box_max_id != -1)
|
if (print_box_max_id != -1)
|
||||||
glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max));
|
glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)m_print_box_max));
|
||||||
|
|
||||||
if (z_range_id != -1)
|
if (z_range_id != -1)
|
||||||
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
|
glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)m_z_range));
|
||||||
|
|
||||||
if (clipping_plane_id != -1)
|
if (clipping_plane_id != -1)
|
||||||
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane));
|
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)m_clipping_plane));
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
if (slope_z_range_id != -1)
|
||||||
|
glsafe(::glUniform2fv(slope_z_range_id, 1, (const GLfloat*)m_slope.z_range.data()));
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
GLVolumeWithIdAndZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
|
||||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||||
volume.first->set_render_color();
|
volume.first->set_render_color();
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
if (color_id >= 0)
|
||||||
|
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)volume.first->render_color));
|
||||||
|
else
|
||||||
|
glsafe(::glColor4fv(volume.first->render_color));
|
||||||
|
|
||||||
|
if (print_box_active_id != -1)
|
||||||
|
glsafe(::glUniform1i(print_box_active_id, volume.first->shader_outside_printer_detection_enabled ? 1 : 0));
|
||||||
|
|
||||||
|
if (print_box_worldmatrix_id != -1)
|
||||||
|
glsafe(::glUniformMatrix4fv(print_box_worldmatrix_id, 1, GL_FALSE, (const GLfloat*)volume.first->world_matrix().cast<float>().data()));
|
||||||
|
|
||||||
|
if (slope_active_id != -1)
|
||||||
|
glsafe(::glUniform1i(slope_active_id, m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower ? 1 : 0));
|
||||||
|
|
||||||
|
if (slope_normal_matrix_id != -1)
|
||||||
|
{
|
||||||
|
Matrix3f normal_matrix = volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>();
|
||||||
|
glsafe(::glUniformMatrix3fv(slope_normal_matrix_id, 1, GL_FALSE, (const GLfloat*)normal_matrix.data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
volume.first->render();
|
||||||
|
#else
|
||||||
volume.first->render(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
volume.first->render(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
|
@ -1816,7 +1854,9 @@ 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;
|
GUI::GLCanvas3DManager _3DScene::s_canvas_mgr;
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
GLModel::GLModel()
|
GLModel::GLModel()
|
||||||
: m_filename("")
|
: m_filename("")
|
||||||
|
@ -1885,7 +1925,16 @@ void GLModel::render() const
|
||||||
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
GLint color_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "uniform_color") : -1;
|
||||||
glcheck();
|
glcheck();
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
if (color_id >= 0)
|
||||||
|
glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)m_volume.render_color));
|
||||||
|
else
|
||||||
|
glsafe(::glColor4fv(m_volume.render_color));
|
||||||
|
|
||||||
|
m_volume.render();
|
||||||
|
#else
|
||||||
m_volume.render(color_id, -1, -1);
|
m_volume.render(color_id, -1, -1);
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
@ -1899,7 +1948,7 @@ void GLModel::render() const
|
||||||
bool GLArrow::on_init()
|
bool GLArrow::on_init()
|
||||||
{
|
{
|
||||||
Pointf3s vertices;
|
Pointf3s vertices;
|
||||||
std::vector<Vec3crd> triangles;
|
std::vector<Vec3i> triangles;
|
||||||
|
|
||||||
// bottom face
|
// bottom face
|
||||||
vertices.emplace_back(0.5, 0.0, -0.1);
|
vertices.emplace_back(0.5, 0.0, -0.1);
|
||||||
|
@ -1965,7 +2014,7 @@ GLCurvedArrow::GLCurvedArrow(unsigned int resolution)
|
||||||
bool GLCurvedArrow::on_init()
|
bool GLCurvedArrow::on_init()
|
||||||
{
|
{
|
||||||
Pointf3s vertices;
|
Pointf3s vertices;
|
||||||
std::vector<Vec3crd> triangles;
|
std::vector<Vec3i> triangles;
|
||||||
|
|
||||||
double ext_radius = 2.5;
|
double ext_radius = 2.5;
|
||||||
double int_radius = 1.5;
|
double int_radius = 1.5;
|
||||||
|
@ -2099,6 +2148,7 @@ 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)
|
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);
|
return Slic3r::GUI::GLCanvas3DManager::get_gl_info().to_string(format_as_html, extensions);
|
||||||
|
@ -2133,5 +2183,6 @@ GUI::GLCanvas3D* _3DScene::get_canvas(wxGLCanvas* canvas)
|
||||||
{
|
{
|
||||||
return s_canvas_mgr.get_canvas(canvas);
|
return s_canvas_mgr.get_canvas(canvas);
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
#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"
|
#include "slic3r/GUI/GLCanvas3DManager.hpp"
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -443,7 +445,9 @@ public:
|
||||||
void set_range(double low, double high);
|
void set_range(double low, double high);
|
||||||
|
|
||||||
void render() const;
|
void render() const;
|
||||||
|
#if !ENABLE_SLOPE_RENDERING
|
||||||
void render(int color_id, int detection_id, int worldmatrix_id) const;
|
void render(int color_id, int detection_id, int worldmatrix_id) const;
|
||||||
|
#endif // !ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
|
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
|
||||||
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
|
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
|
||||||
|
@ -479,20 +483,36 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// min and max vertex of the print box volume
|
// min and max vertex of the print box volume
|
||||||
float print_box_min[3];
|
float m_print_box_min[3];
|
||||||
float print_box_max[3];
|
float m_print_box_max[3];
|
||||||
|
|
||||||
// z range for clipping in shaders
|
// z range for clipping in shaders
|
||||||
float z_range[2];
|
float m_z_range[2];
|
||||||
|
|
||||||
// plane coeffs for clipping in shaders
|
// plane coeffs for clipping in shaders
|
||||||
float clipping_plane[4];
|
float m_clipping_plane[4];
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
struct Slope
|
||||||
|
{
|
||||||
|
// toggle for slope rendering
|
||||||
|
bool active{ false };
|
||||||
|
// [0] = yellow, [1] = red
|
||||||
|
std::array<float, 2> z_range;
|
||||||
|
};
|
||||||
|
|
||||||
|
Slope m_slope;
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLVolumePtrs volumes;
|
GLVolumePtrs volumes;
|
||||||
|
|
||||||
GLVolumeCollection() {};
|
#if ENABLE_SLOPE_RENDERING
|
||||||
~GLVolumeCollection() { clear(); };
|
GLVolumeCollection() { set_default_slope_z_range(); }
|
||||||
|
#else
|
||||||
|
GLVolumeCollection() = default;
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
~GLVolumeCollection() { clear(); }
|
||||||
|
|
||||||
std::vector<int> load_object(
|
std::vector<int> load_object(
|
||||||
const ModelObject *model_object,
|
const ModelObject *model_object,
|
||||||
|
@ -543,12 +563,21 @@ public:
|
||||||
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
|
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
|
||||||
|
|
||||||
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
|
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
|
||||||
print_box_min[0] = min_x; print_box_min[1] = min_y; print_box_min[2] = min_z;
|
m_print_box_min[0] = min_x; m_print_box_min[1] = min_y; m_print_box_min[2] = min_z;
|
||||||
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
|
m_print_box_max[0] = max_x; m_print_box_max[1] = max_y; m_print_box_max[2] = max_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_z_range(float min_z, float max_z) { z_range[0] = min_z; z_range[1] = max_z; }
|
void set_z_range(float min_z, float max_z) { m_z_range[0] = min_z; m_z_range[1] = max_z; }
|
||||||
void set_clipping_plane(const double* coeffs) { clipping_plane[0] = coeffs[0]; clipping_plane[1] = coeffs[1]; clipping_plane[2] = coeffs[2]; clipping_plane[3] = coeffs[3]; }
|
void set_clipping_plane(const double* coeffs) { m_clipping_plane[0] = coeffs[0]; m_clipping_plane[1] = coeffs[1]; m_clipping_plane[2] = coeffs[2]; m_clipping_plane[3] = coeffs[3]; }
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
bool is_slope_active() const { return m_slope.active; }
|
||||||
|
void set_slope_active(bool active) { m_slope.active = active; }
|
||||||
|
|
||||||
|
const std::array<float, 2>& get_slope_z_range() const { return m_slope.z_range; }
|
||||||
|
void set_slope_z_range(const std::array<float, 2>& range) { m_slope.z_range = range; }
|
||||||
|
void set_default_slope_z_range() { m_slope.z_range = { -::cos(Geometry::deg2rad(90.0f - 45.0f)), -::cos(Geometry::deg2rad(90.0f - 70.0f)) }; }
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
// returns true if all the volumes are completely contained in the print volume
|
// returns true if all the volumes are completely contained in the print volume
|
||||||
// returns the containment state in the given out_state, if non-null
|
// returns the containment state in the given out_state, if non-null
|
||||||
|
@ -639,10 +668,17 @@ 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
|
||||||
|
#else
|
||||||
class _3DScene
|
class _3DScene
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
{
|
{
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
static GUI::GLCanvas3DManager s_canvas_mgr;
|
static GUI::GLCanvas3DManager s_canvas_mgr;
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
public:
|
public:
|
||||||
static std::string get_gl_info(bool format_as_html, bool extensions);
|
static std::string get_gl_info(bool format_as_html, bool extensions);
|
||||||
|
|
||||||
|
@ -654,6 +690,7 @@ public:
|
||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
static GUI::GLCanvas3D* get_canvas(wxGLCanvas* canvas);
|
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);
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#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/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"
|
||||||
|
|
||||||
|
@ -359,7 +362,11 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
|
||||||
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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
|
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);
|
||||||
}
|
}
|
||||||
|
@ -774,6 +781,13 @@ bool GLCanvas3D::WarningTexture::generate(const std::string& msg_utf8, const GLC
|
||||||
#else
|
#else
|
||||||
// select default font
|
// select default font
|
||||||
const float scale = canvas.get_canvas_size().get_scale_factor();
|
const float scale = canvas.get_canvas_size().get_scale_factor();
|
||||||
|
#if ENABLE_RETINA_GL
|
||||||
|
// For non-visible or non-created window getBackingScaleFactor function return 0.0 value.
|
||||||
|
// And using of the zero scale causes a crash, when we trying to draw text to the (0,0) rectangle
|
||||||
|
// https://github.com/prusa3d/PrusaSlicer/issues/3916
|
||||||
|
if (scale <= 0.0f)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
|
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -851,7 +865,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
|
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;
|
||||||
|
@ -1218,7 +1236,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)canvas.get_camera().get_inv_zoom();
|
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;
|
||||||
|
@ -1244,7 +1266,11 @@ 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();
|
||||||
|
#else
|
||||||
const Camera& camera = m_canvas.get_camera();
|
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;
|
||||||
|
@ -1426,6 +1452,62 @@ void GLCanvas3D::Tooltip::render(const Vec2d& mouse_position, GLCanvas3D& canvas
|
||||||
}
|
}
|
||||||
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
void GLCanvas3D::Slope::render() const
|
||||||
|
{
|
||||||
|
if (is_shown())
|
||||||
|
{
|
||||||
|
const std::array<float, 2>& z_range = m_volumes.get_slope_z_range();
|
||||||
|
std::array<float, 2> angle_range = { Geometry::rad2deg(::acos(z_range[0])) - 90.0f, Geometry::rad2deg(::acos(z_range[1])) - 90.0f };
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
const Size& cnv_size = m_canvas.get_canvas_size();
|
||||||
|
imgui.set_next_window_pos((float)cnv_size.get_width(), (float)cnv_size.get_height(), ImGuiCond_Always, 1.0f, 1.0f);
|
||||||
|
imgui.begin(_(L("Slope visualization")), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
imgui.text(_(L("Facets' normal angle range (degrees)")) + ":");
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.75f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 1.0f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.85f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.25f, 0.0f, 1.0f));
|
||||||
|
if (ImGui::SliderFloat("##yellow", &angle_range[0], 0.0f, 90.0f, "%.1f"))
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
if (angle_range[1] < angle_range[0])
|
||||||
|
angle_range[1] = angle_range[0];
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.75f, 0.0f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(1.0f, 0.0f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(0.85f, 0.0f, 0.0f, 0.5f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.25f, 0.0f, 0.0f, 1.0f));
|
||||||
|
if (ImGui::SliderFloat("##red", &angle_range[1], 0.0f, 90.0f, "%.1f"))
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
if (angle_range[0] > angle_range[1])
|
||||||
|
angle_range[0] = angle_range[1];
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (imgui.button(_(L("Default"))))
|
||||||
|
m_volumes.set_default_slope_z_range();
|
||||||
|
|
||||||
|
// to let the dialog immediately showup without waiting for a mouse move
|
||||||
|
if (ImGui::GetWindowContentRegionWidth() + 2.0f * ImGui::GetStyle().WindowPadding.x != ImGui::CalcWindowExpectedSize(ImGui::GetCurrentWindow()).x)
|
||||||
|
m_canvas.request_extra_frame();
|
||||||
|
|
||||||
|
imgui.end();
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
m_volumes.set_slope_z_range({ -::cos(Geometry::deg2rad(90.0f - angle_range[0])), -::cos(Geometry::deg2rad(90.0f - angle_range[1])) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
|
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, RBtnEvent);
|
||||||
|
@ -1457,16 +1539,22 @@ 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)
|
||||||
|
#else
|
||||||
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
|
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_bed(bed)
|
||||||
, m_camera(camera)
|
, m_camera(camera)
|
||||||
, m_view_toolbar(view_toolbar)
|
, 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_gizmos(*this)
|
, m_gizmos(*this)
|
||||||
|
@ -1494,14 +1582,19 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar
|
||||||
#endif // ENABLE_RENDER_PICKING_PASS
|
#endif // ENABLE_RENDER_PICKING_PASS
|
||||||
, m_render_sla_auxiliaries(true)
|
, m_render_sla_auxiliaries(true)
|
||||||
, m_labels(*this)
|
, m_labels(*this)
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
, m_slope(*this, m_volumes)
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
{
|
{
|
||||||
if (m_canvas != nullptr) {
|
if (m_canvas != nullptr) {
|
||||||
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
|
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
|
||||||
m_view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size);
|
m_view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size);
|
||||||
#endif
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#endif // ENABLE_RETINA_GL
|
||||||
}
|
}
|
||||||
|
|
||||||
m_selection.set_volumes(&m_volumes.volumes);
|
m_selection.set_volumes(&m_volumes.volumes);
|
||||||
|
@ -1614,6 +1707,18 @@ void GLCanvas3D::reset_volumes()
|
||||||
if (!m_initialized)
|
if (!m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
if (m_volumes.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_set_current();
|
||||||
|
|
||||||
|
m_selection.clear();
|
||||||
|
m_volumes.clear();
|
||||||
|
m_dirty = true;
|
||||||
|
|
||||||
|
_set_warning_texture(WarningTexture::ObjectOutside, false);
|
||||||
|
#else
|
||||||
_set_current();
|
_set_current();
|
||||||
|
|
||||||
if (!m_volumes.empty())
|
if (!m_volumes.empty())
|
||||||
|
@ -1624,6 +1729,7 @@ void GLCanvas3D::reset_volumes()
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_warning_texture(WarningTexture::ObjectOutside, false);
|
_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
|
||||||
|
@ -1705,7 +1811,11 @@ 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;
|
||||||
|
#else
|
||||||
m_camera.requires_zoom_to_bed = true;
|
m_camera.requires_zoom_to_bed = true;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,6 +1824,15 @@ void GLCanvas3D::set_color_by(const std::string& value)
|
||||||
m_color_by = value;
|
m_color_by = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas3D::refresh_camera_scene_box()
|
||||||
|
{
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
wxGetApp().plater()->get_camera().set_scene_box(scene_bounding_box());
|
||||||
|
#else
|
||||||
|
m_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
|
||||||
{
|
{
|
||||||
BoundingBoxf3 bb;
|
BoundingBoxf3 bb;
|
||||||
|
@ -1728,7 +1847,11 @@ 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));
|
||||||
|
#else
|
||||||
bb.merge(m_bed.get_bounding_box(true));
|
bb.merge(m_bed.get_bounding_box(true));
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
if (m_config != nullptr)
|
if (m_config != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1781,6 +1904,11 @@ bool GLCanvas3D::is_reload_delayed() const
|
||||||
|
|
||||||
void GLCanvas3D::enable_layers_editing(bool enable)
|
void GLCanvas3D::enable_layers_editing(bool enable)
|
||||||
{
|
{
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
if (enable && m_slope.is_shown())
|
||||||
|
m_slope.show(false);
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
m_layers_editing.set_enabled(enable);
|
m_layers_editing.set_enabled(enable);
|
||||||
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
|
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
|
||||||
for (unsigned int idx : idxs)
|
for (unsigned int idx : idxs)
|
||||||
|
@ -1841,7 +1969,11 @@ 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));
|
||||||
|
#else
|
||||||
_zoom_to_box(m_bed.get_bounding_box(false));
|
_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()
|
||||||
|
@ -1859,7 +1991,11 @@ 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);
|
||||||
|
#else
|
||||||
m_camera.select_view(direction);
|
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();
|
||||||
}
|
}
|
||||||
|
@ -1887,14 +2023,26 @@ 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())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!is_initialized() && !init())
|
||||||
|
return;
|
||||||
|
#else
|
||||||
if (! _is_shown_on_screen() || !_set_current() || !_3DScene::init(m_canvas))
|
if (! _is_shown_on_screen() || !_set_current() || !_3DScene::init(m_canvas))
|
||||||
return;
|
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())
|
||||||
|
#else
|
||||||
if (m_bed.get_shape().empty())
|
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));
|
||||||
|
@ -1906,6 +2054,20 @@ 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.apply_viewport(0, 0, std::max(10u, (unsigned int)cnv_size.get_width()), std::max(10u, (unsigned int)cnv_size.get_height()));
|
||||||
|
|
||||||
|
if (camera.requires_zoom_to_bed)
|
||||||
|
{
|
||||||
|
zoom_to_bed();
|
||||||
|
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
|
||||||
|
camera.requires_zoom_to_bed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
camera.apply_view_matrix();
|
||||||
|
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()));
|
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)
|
if (m_camera.requires_zoom_to_bed)
|
||||||
|
@ -1917,6 +2079,7 @@ void GLCanvas3D::render()
|
||||||
|
|
||||||
m_camera.apply_view_matrix();
|
m_camera.apply_view_matrix();
|
||||||
m_camera.apply_projection(_max_bounding_box(true, true));
|
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));
|
||||||
|
@ -1946,7 +2109,11 @@ 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);
|
||||||
|
#else
|
||||||
_render_bed(!m_camera.is_looking_downward(), true);
|
_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();
|
||||||
|
@ -1955,7 +2122,7 @@ void GLCanvas3D::render()
|
||||||
// we need to set the mouse's scene position here because the depth buffer
|
// we need to set the mouse's scene position here because the depth buffer
|
||||||
// could be invalidated by the following gizmo render methods
|
// could be invalidated by the following gizmo render methods
|
||||||
// this position is used later into on_mouse() to drag the objects
|
// this position is used later into on_mouse() to drag the objects
|
||||||
m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<int>());
|
m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<coord_t>());
|
||||||
|
|
||||||
_render_current_gizmo();
|
_render_current_gizmo();
|
||||||
_render_selection_sidebar_hints();
|
_render_selection_sidebar_hints();
|
||||||
|
@ -2015,8 +2182,12 @@ void GLCanvas3D::render()
|
||||||
tooltip = m_undoredo_toolbar.get_tooltip();
|
tooltip = m_undoredo_toolbar.get_tooltip();
|
||||||
|
|
||||||
if (tooltip.empty())
|
if (tooltip.empty())
|
||||||
tooltip = m_view_toolbar.get_tooltip();
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
}
|
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);
|
||||||
|
|
||||||
|
@ -2060,8 +2231,13 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w,
|
||||||
{
|
{
|
||||||
switch (GLCanvas3DManager::get_framebuffers_type())
|
switch (GLCanvas3DManager::get_framebuffers_type())
|
||||||
{
|
{
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
case GLCanvas3DManager::EFramebufferType::Arb: { _render_thumbnail_framebuffer(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_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; }
|
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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2166,8 +2342,15 @@ 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)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_set_current();
|
||||||
|
#else
|
||||||
if (m_initialized)
|
if (m_initialized)
|
||||||
_set_current();
|
_set_current();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
struct ModelVolumeState {
|
struct ModelVolumeState {
|
||||||
ModelVolumeState(const GLVolume* volume) :
|
ModelVolumeState(const GLVolume* volume) :
|
||||||
|
@ -2769,8 +2952,13 @@ 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();
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state();
|
||||||
|
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera());
|
||||||
|
#else
|
||||||
m_dirty |= m_view_toolbar.update_items_state();
|
m_dirty |= m_view_toolbar.update_items_state();
|
||||||
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(m_camera);
|
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)
|
||||||
|
@ -2911,12 +3099,27 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||||
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
|
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'b': { zoom_to_bed(); break; }
|
case 'b': { zoom_to_bed(); break; }
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
case 'D':
|
||||||
|
case 'd': {
|
||||||
|
if (!is_layers_editing_enabled())
|
||||||
|
{
|
||||||
|
m_slope.show(!m_slope.is_shown());
|
||||||
|
m_dirty = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
case 'E':
|
case 'E':
|
||||||
case 'e': { m_labels.show(!m_labels.is_shown()); m_dirty = true; break; }
|
case 'e': { m_labels.show(!m_labels.is_shown()); m_dirty = true; break; }
|
||||||
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; }
|
||||||
|
#else
|
||||||
case 'k': { m_camera.select_next_type(); m_dirty = true; break; }
|
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
|
||||||
|
@ -3043,7 +3246,11 @@ 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);
|
||||||
|
#else
|
||||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> inv_view_3x3 = m_camera.get_view_matrix().inverse().matrix().block(0, 0, 3, 3);
|
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;
|
||||||
}
|
}
|
||||||
|
@ -3369,7 +3576,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
if (wxGetApp().plater()->get_view_toolbar().on_mouse(evt, *this))
|
||||||
|
#else
|
||||||
if (m_view_toolbar.on_mouse(evt, *this))
|
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();
|
||||||
|
@ -3532,7 +3743,12 @@ 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();
|
||||||
|
if (std::abs(camera.get_dir_forward()(2)) < EPSILON)
|
||||||
|
#else
|
||||||
if (std::abs(m_camera.get_dir_forward()(2)) < EPSILON)
|
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);
|
||||||
|
@ -3545,8 +3761,13 @@ 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_up = camera.get_dir_up();
|
||||||
|
#else
|
||||||
Vec3d camera_right = m_camera.get_dir_right();
|
Vec3d camera_right = m_camera.get_dir_right();
|
||||||
Vec3d camera_up = m_camera.get_dir_up();
|
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);
|
||||||
|
@ -3596,15 +3817,25 @@ 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.));
|
||||||
|
#else
|
||||||
m_camera.rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
|
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.recover_from_free_camera();
|
||||||
|
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.recover_from_free_camera();
|
||||||
m_camera.rotate_on_sphere(rot.x(), rot.y(), wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() != ptSLA);
|
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;
|
||||||
|
@ -3620,14 +3851,23 @@ 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();
|
||||||
|
#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.set_target(camera.get_target() + orig - cur_pos);
|
||||||
|
#else
|
||||||
m_camera.recover_from_free_camera();
|
m_camera.recover_from_free_camera();
|
||||||
|
|
||||||
m_camera.set_target(m_camera.get_target() + orig - cur_pos);
|
m_camera.set_target(m_camera.get_target() + orig - cur_pos);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4076,7 +4316,12 @@ 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.set_zoom(camera.get_zoom() * new_scaling / orig_scaling);
|
||||||
|
#else
|
||||||
m_camera.set_zoom(m_camera.get_zoom() * new_scaling / orig_scaling);
|
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
|
||||||
|
@ -4109,16 +4354,13 @@ Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
|
||||||
return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
|
return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLCanvas3D::refresh_camera_scene_box()
|
|
||||||
{
|
|
||||||
m_camera.set_scene_box(scene_bounding_box());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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();
|
||||||
|
#else
|
||||||
return factor * m_bed.get_bounding_box(false).max_size();
|
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)
|
||||||
|
@ -4181,7 +4423,11 @@ 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();
|
||||||
|
#else
|
||||||
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
|
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);
|
||||||
|
@ -4281,7 +4527,11 @@ 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());
|
||||||
|
#else
|
||||||
BoundingBoxf3 t_bed_box = m_bed.get_bounding_box(true).transformed(camera.get_view_matrix());
|
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);
|
||||||
}
|
}
|
||||||
|
@ -4558,7 +4808,11 @@ 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());
|
||||||
|
#else
|
||||||
m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height());
|
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()
|
||||||
|
@ -4883,19 +5137,31 @@ 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));
|
||||||
|
#else
|
||||||
bb.merge(m_bed.get_bounding_box(include_bed_model));
|
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);
|
||||||
|
#else
|
||||||
m_camera.zoom_to_box(box, margin_factor);
|
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);
|
||||||
|
#else
|
||||||
m_camera.update_zoom(zoom);
|
m_camera.update_zoom(zoom);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5086,7 +5352,11 @@ void GLCanvas3D::_render_bed(float theta, bool show_axes) const
|
||||||
#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 // ENABLE_RETINA_GL
|
#endif // ENABLE_RETINA_GL
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
wxGetApp().plater()->get_bed().render(const_cast<GLCanvas3D&>(*this), theta, scale_factor, show_axes);
|
||||||
|
#else
|
||||||
m_bed.render(const_cast<GLCanvas3D&>(*this), theta, scale_factor, show_axes);
|
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
|
||||||
|
@ -5105,7 +5375,11 @@ 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);
|
||||||
|
#else
|
||||||
const BoundingBoxf3& bed_bb = m_bed.get_bounding_box(false);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -5121,19 +5395,37 @@ 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) {
|
||||||
|
// Which volume to paint without the layer height profile shader?
|
||||||
|
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) {
|
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?
|
// 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);
|
||||||
});
|
});
|
||||||
|
#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) {
|
||||||
|
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) {
|
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);
|
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());
|
||||||
|
#else
|
||||||
m_volumes.render(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
|
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();
|
||||||
|
@ -5163,9 +5455,16 @@ 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();
|
||||||
|
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.005)));
|
||||||
|
// ensure that the overlay fits the frustrum near z plane
|
||||||
|
double gui_scale = camera.get_gui_scale();
|
||||||
|
#else
|
||||||
glsafe(::glTranslated(0.0, 0.0, -(m_camera.get_near_z() + 0.005)));
|
glsafe(::glTranslated(0.0, 0.0, -(m_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 = m_camera.get_gui_scale();
|
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();
|
||||||
|
@ -5202,6 +5501,10 @@ void GLCanvas3D::_render_overlays() const
|
||||||
}
|
}
|
||||||
m_labels.render(sorted_instances);
|
m_labels.render(sorted_instances);
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
m_slope.render();
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
glsafe(::glPopMatrix());
|
glsafe(::glPopMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5228,7 +5531,11 @@ 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();
|
||||||
|
#else
|
||||||
const Transform3d& view_matrix = m_camera.get_view_matrix();
|
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)
|
||||||
|
@ -5277,7 +5584,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)m_camera.get_inv_zoom();
|
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;
|
||||||
|
@ -5292,7 +5603,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)m_camera.get_inv_zoom();
|
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;
|
||||||
|
@ -5302,25 +5617,50 @@ void GLCanvas3D::_render_undoredo_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();
|
||||||
|
#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
|
||||||
|
#else
|
||||||
m_view_toolbar.set_scale(scale); //! #ys_FIXME_experiment
|
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
|
||||||
|
#else
|
||||||
m_view_toolbar.set_icons_size(size); //! #ys_FIXME_experiment
|
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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)m_camera.get_inv_zoom();
|
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;
|
||||||
|
#else
|
||||||
float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar.get_height()) * inv_zoom;
|
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.render(*this);
|
||||||
|
#else
|
||||||
m_view_toolbar.set_position(top, left);
|
m_view_toolbar.set_position(top, left);
|
||||||
m_view_toolbar.render(*this);
|
m_view_toolbar.render(*this);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_SHOW_CAMERA_TARGET
|
#if ENABLE_SHOW_CAMERA_TARGET
|
||||||
|
@ -5599,10 +5939,16 @@ 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 std::array<int, 4>& viewport = camera.get_viewport();
|
||||||
|
const Transform3d& modelview_matrix = camera.get_view_matrix();
|
||||||
|
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||||
|
#else
|
||||||
const std::array<int, 4>& viewport = m_camera.get_viewport();
|
const std::array<int, 4>& viewport = m_camera.get_viewport();
|
||||||
const Transform3d& modelview_matrix = m_camera.get_view_matrix();
|
const Transform3d& modelview_matrix = m_camera.get_view_matrix();
|
||||||
const Transform3d& projection_matrix = m_camera.get_projection_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;
|
||||||
|
|
|
@ -31,6 +31,9 @@ class wxMouseEvent;
|
||||||
class wxTimerEvent;
|
class wxTimerEvent;
|
||||||
class wxPaintEvent;
|
class wxPaintEvent;
|
||||||
class wxGLCanvas;
|
class wxGLCanvas;
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
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__
|
||||||
|
@ -406,6 +409,24 @@ private:
|
||||||
};
|
};
|
||||||
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
class Slope
|
||||||
|
{
|
||||||
|
bool m_enabled{ false };
|
||||||
|
GLCanvas3D& m_canvas;
|
||||||
|
GLVolumeCollection& m_volumes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Slope(GLCanvas3D& canvas, GLVolumeCollection& volumes) : m_canvas(canvas), m_volumes(volumes) {}
|
||||||
|
|
||||||
|
void enable(bool enable) { m_enabled = enable; }
|
||||||
|
bool is_enabled() const { return m_enabled; }
|
||||||
|
void show(bool show) { m_volumes.set_slope_active(m_enabled ? show : false); }
|
||||||
|
bool is_shown() const { return m_volumes.is_slope_active(); }
|
||||||
|
void render() const;
|
||||||
|
};
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum ECursorType : unsigned char
|
enum ECursorType : unsigned char
|
||||||
{
|
{
|
||||||
|
@ -423,9 +444,11 @@ 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;
|
Bed3D& m_bed;
|
||||||
Camera& m_camera;
|
Camera& m_camera;
|
||||||
GLToolbar& m_view_toolbar;
|
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;
|
||||||
|
@ -487,11 +510,22 @@ private:
|
||||||
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
#if ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
||||||
mutable Tooltip m_tooltip;
|
mutable Tooltip m_tooltip;
|
||||||
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
#endif // ENABLE_CANVAS_TOOLTIP_USING_IMGUI
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
Slope m_slope;
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
explicit GLCanvas3D(wxGLCanvas* canvas);
|
||||||
|
#else
|
||||||
GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
|
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; }
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
void set_context(wxGLContext* context) { m_context = context; }
|
void set_context(wxGLContext* context) { m_context = context; }
|
||||||
|
|
||||||
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
|
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
|
||||||
|
@ -538,9 +572,14 @@ 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();
|
||||||
|
#else
|
||||||
|
void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); }
|
||||||
const Camera& get_camera() const { return m_camera; }
|
const Camera& get_camera() const { return m_camera; }
|
||||||
const Shader& get_shader() const { return m_shader; }
|
|
||||||
Camera& get_camera() { return m_camera; }
|
Camera& get_camera() { return m_camera; }
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Shader& get_shader() const { return m_shader; }
|
||||||
|
|
||||||
BoundingBoxf3 volumes_bounding_box() const;
|
BoundingBoxf3 volumes_bounding_box() const;
|
||||||
BoundingBoxf3 scene_bounding_box() const;
|
BoundingBoxf3 scene_bounding_box() const;
|
||||||
|
@ -564,6 +603,9 @@ public:
|
||||||
void enable_undoredo_toolbar(bool enable);
|
void enable_undoredo_toolbar(bool enable);
|
||||||
void enable_dynamic_background(bool enable);
|
void enable_dynamic_background(bool enable);
|
||||||
void enable_labels(bool enable) { m_labels.enable(enable); }
|
void enable_labels(bool enable) { m_labels.enable(enable); }
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
void enable_slope(bool enable) { m_slope.enable(enable); }
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
void allow_multisample(bool allow);
|
void allow_multisample(bool allow);
|
||||||
|
|
||||||
void zoom_to_bed();
|
void zoom_to_bed();
|
||||||
|
@ -636,7 +678,9 @@ 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(); }
|
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(); }
|
||||||
|
@ -668,7 +712,6 @@ public:
|
||||||
Linef3 mouse_ray(const Point& mouse_pos);
|
Linef3 mouse_ray(const Point& mouse_pos);
|
||||||
|
|
||||||
void set_mouse_as_dragging() { m_mouse.dragging = true; }
|
void set_mouse_as_dragging() { m_mouse.dragging = true; }
|
||||||
void refresh_camera_scene_box();
|
|
||||||
bool is_mouse_dragging() const { return m_mouse.dragging; }
|
bool is_mouse_dragging() const { return m_mouse.dragging; }
|
||||||
|
|
||||||
double get_size_proportional_to_max_bed_size(double factor) const;
|
double get_size_proportional_to_max_bed_size(double factor) const;
|
||||||
|
@ -690,6 +733,11 @@ public:
|
||||||
bool are_labels_shown() const { return m_labels.is_shown(); }
|
bool are_labels_shown() const { return m_labels.is_shown(); }
|
||||||
void show_labels(bool show) { m_labels.show(show); }
|
void show_labels(bool show) { m_labels.show(show); }
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
bool is_slope_shown() const { return m_slope.is_shown(); }
|
||||||
|
void show_slope(bool show) { m_slope.show(show); }
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_shown_on_screen() const;
|
bool _is_shown_on_screen() const;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "libslic3r/libslic3r.h"
|
||||||
#include "GLCanvas3DManager.hpp"
|
#include "GLCanvas3DManager.hpp"
|
||||||
#include "../../slic3r/GUI/GUI.hpp"
|
#include "../../slic3r/GUI/GUI.hpp"
|
||||||
#include "../../slic3r/GUI/AppConfig.hpp"
|
#include "../../slic3r/GUI/AppConfig.hpp"
|
||||||
|
@ -7,7 +8,9 @@
|
||||||
|
|
||||||
#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>
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
#include <wx/glcanvas.h>
|
#include <wx/glcanvas.h>
|
||||||
#include <wx/timer.h>
|
#include <wx/timer.h>
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
@ -17,8 +20,10 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
// Part of temporary hack to remove crash when 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
|
||||||
#include <wx/platinfo.h>
|
#include <wx/platinfo.h>
|
||||||
|
#endif // __APPLE__
|
||||||
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -28,6 +33,7 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
GLCanvas3DManager::GLInfo::GLInfo()
|
GLCanvas3DManager::GLInfo::GLInfo()
|
||||||
: m_detected(false)
|
: m_detected(false)
|
||||||
, m_version("")
|
, m_version("")
|
||||||
|
@ -38,6 +44,7 @@ GLCanvas3DManager::GLInfo::GLInfo()
|
||||||
, m_max_anisotropy(0.0f)
|
, m_max_anisotropy(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
const std::string& GLCanvas3DManager::GLInfo::get_version() const
|
const std::string& GLCanvas3DManager::GLInfo::get_version() const
|
||||||
{
|
{
|
||||||
|
@ -196,27 +203,57 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown;
|
|
||||||
bool GLCanvas3DManager::s_compressed_textures_supported = false;
|
|
||||||
GLCanvas3DManager::EFramebufferType GLCanvas3DManager::s_framebuffers_type = GLCanvas3DManager::FB_None;
|
|
||||||
GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info;
|
GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info;
|
||||||
|
bool GLCanvas3DManager::s_compressed_textures_supported = false;
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::EMultisampleState::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
|
||||||
GLCanvas3DManager::OSInfo GLCanvas3DManager::s_os_info;
|
GLCanvas3DManager::OSInfo GLCanvas3DManager::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
|
||||||
GLCanvas3DManager::GLCanvas3DManager()
|
GLCanvas3DManager::GLCanvas3DManager()
|
||||||
: m_context(nullptr)
|
: m_context(nullptr)
|
||||||
, m_gl_initialized(false)
|
, m_gl_initialized(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
GLCanvas3DManager::~GLCanvas3DManager()
|
GLCanvas3DManager::~GLCanvas3DManager()
|
||||||
{
|
{
|
||||||
this->destroy();
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#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 with newer wxWidgets
|
||||||
|
// The crash is triggered inside wxGLContext destructor
|
||||||
|
if (s_os_info.major != 10 || s_os_info.minor != 9 || s_os_info.micro != 5)
|
||||||
|
{
|
||||||
|
#endif //__APPLE__
|
||||||
|
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
|
|
||||||
|
if (m_context != nullptr)
|
||||||
|
delete m_context;
|
||||||
|
|
||||||
|
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
|
#ifdef __APPLE__
|
||||||
|
}
|
||||||
|
#endif //__APPLE__
|
||||||
|
#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 GLCanvas3DManager::add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
|
bool GLCanvas3DManager::add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar)
|
||||||
{
|
{
|
||||||
if (canvas == nullptr)
|
if (canvas == nullptr)
|
||||||
|
@ -239,7 +276,7 @@ bool GLCanvas3DManager::add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLTo
|
||||||
|
|
||||||
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Part of temporary hack to remove crash when closing on OSX 10.9.5
|
// 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.major = wxPlatformInfo::Get().GetOSMajorVersion();
|
||||||
s_os_info.minor = wxPlatformInfo::Get().GetOSMinorVersion();
|
s_os_info.minor = wxPlatformInfo::Get().GetOSMinorVersion();
|
||||||
s_os_info.micro = wxPlatformInfo::Get().GetOSMicroVersion();
|
s_os_info.micro = wxPlatformInfo::Get().GetOSMicroVersion();
|
||||||
|
@ -277,28 +314,50 @@ void GLCanvas3DManager::remove_all()
|
||||||
m_canvases.clear();
|
m_canvases.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GLCanvas3DManager::count() const
|
size_t GLCanvas3DManager::count() const
|
||||||
{
|
{
|
||||||
return (unsigned int)m_canvases.size();
|
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()
|
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)
|
||||||
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Unable to init glew library";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
glewInit();
|
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)
|
||||||
|
s_framebuffers_type = EFramebufferType::Arb;
|
||||||
|
else if (GLEW_EXT_framebuffer_object)
|
||||||
|
s_framebuffers_type = EFramebufferType::Ext;
|
||||||
|
else
|
||||||
|
s_framebuffers_type = EFramebufferType::Unknown;
|
||||||
|
#else
|
||||||
if (GLEW_ARB_framebuffer_object)
|
if (GLEW_ARB_framebuffer_object)
|
||||||
s_framebuffers_type = FB_Arb;
|
s_framebuffers_type = FB_Arb;
|
||||||
else if (GLEW_EXT_framebuffer_object)
|
else if (GLEW_EXT_framebuffer_object)
|
||||||
s_framebuffers_type = FB_Ext;
|
s_framebuffers_type = FB_Ext;
|
||||||
else
|
else
|
||||||
s_framebuffers_type = FB_None;
|
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.
|
||||||
|
@ -314,8 +373,31 @@ void GLCanvas3DManager::init_gl()
|
||||||
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;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
wxGLContext* GLCanvas3DManager::init_glcontext(wxGLCanvas& canvas)
|
||||||
|
{
|
||||||
|
if (m_context == nullptr)
|
||||||
|
{
|
||||||
|
m_context = new wxGLContext(&canvas);
|
||||||
|
|
||||||
|
#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
|
||||||
|
}
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
#else
|
||||||
bool GLCanvas3DManager::init(wxGLCanvas* canvas)
|
bool GLCanvas3DManager::init(wxGLCanvas* canvas)
|
||||||
{
|
{
|
||||||
CanvasesMap::const_iterator it = do_get_canvas(canvas);
|
CanvasesMap::const_iterator it = do_get_canvas(canvas);
|
||||||
|
@ -331,7 +413,7 @@ void GLCanvas3DManager::destroy()
|
||||||
{
|
{
|
||||||
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
#if ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// this is a temporary ugly hack to solve the crash happening when closing the application on OSX 10.9.5
|
// 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
|
// the crash is inside wxGLContext destructor
|
||||||
if (s_os_info.major == 10 && s_os_info.minor == 9 && s_os_info.micro == 5)
|
if (s_os_info.major == 10 && s_os_info.minor == 9 && s_os_info.micro == 5)
|
||||||
return;
|
return;
|
||||||
|
@ -342,14 +424,21 @@ void GLCanvas3DManager::destroy()
|
||||||
m_context = nullptr;
|
m_context = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
GLCanvas3D* GLCanvas3DManager::get_canvas(wxGLCanvas* canvas)
|
GLCanvas3D* GLCanvas3DManager::get_canvas(wxGLCanvas* canvas)
|
||||||
{
|
{
|
||||||
CanvasesMap::const_iterator it = do_get_canvas(canvas);
|
CanvasesMap::const_iterator it = do_get_canvas(canvas);
|
||||||
return (it != m_canvases.end()) ? it->second : nullptr;
|
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)
|
wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
{
|
{
|
||||||
int attribList[] = {
|
int attribList[] = {
|
||||||
WX_GL_RGBA,
|
WX_GL_RGBA,
|
||||||
|
@ -367,7 +456,11 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
if (s_multisample == EMultisampleState::Unknown)
|
||||||
|
#else
|
||||||
if (s_multisample == MS_Unknown)
|
if (s_multisample == MS_Unknown)
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
{
|
{
|
||||||
detect_multisample(attribList);
|
detect_multisample(attribList);
|
||||||
// // debug output
|
// // debug output
|
||||||
|
@ -377,9 +470,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);
|
||||||
|
#else
|
||||||
return new wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
|
return new wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::do_get_canvas(wxGLCanvas* canvas)
|
GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::do_get_canvas(wxGLCanvas* canvas)
|
||||||
{
|
{
|
||||||
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
|
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
|
||||||
|
@ -397,12 +495,17 @@ bool GLCanvas3DManager::init(GLCanvas3D& canvas)
|
||||||
|
|
||||||
return canvas.init();
|
return canvas.init();
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
void GLCanvas3DManager::detect_multisample(int* attribList)
|
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;
|
||||||
|
#else
|
||||||
s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? MS_Enabled : MS_Disabled;
|
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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,22 +23,43 @@ class PrintObject;
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class GLCanvas3D;
|
class GLCanvas3D;
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
class Bed3D;
|
class Bed3D;
|
||||||
class GLToolbar;
|
class GLToolbar;
|
||||||
struct Camera;
|
struct Camera;
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
class GLCanvas3DManager
|
class GLCanvas3DManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
enum class EFramebufferType : unsigned char
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Arb,
|
||||||
|
Ext
|
||||||
|
};
|
||||||
|
#else
|
||||||
enum EFramebufferType : unsigned char
|
enum EFramebufferType : unsigned char
|
||||||
{
|
{
|
||||||
FB_None,
|
FB_None,
|
||||||
FB_Arb,
|
FB_Arb,
|
||||||
FB_Ext
|
FB_Ext
|
||||||
};
|
};
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
class GLInfo
|
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 bool m_detected;
|
||||||
|
|
||||||
mutable std::string m_version;
|
mutable std::string m_version;
|
||||||
|
@ -48,9 +69,14 @@ public:
|
||||||
|
|
||||||
mutable int m_max_tex_size;
|
mutable int m_max_tex_size;
|
||||||
mutable float m_max_anisotropy;
|
mutable float m_max_anisotropy;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
GLInfo() = default;
|
||||||
|
#else
|
||||||
GLInfo();
|
GLInfo();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
const std::string& get_version() const;
|
const std::string& get_version() const;
|
||||||
const std::string& get_glsl_version() const;
|
const std::string& get_glsl_version() const;
|
||||||
|
@ -70,6 +96,7 @@ public:
|
||||||
|
|
||||||
#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
|
||||||
struct OSInfo
|
struct OSInfo
|
||||||
{
|
{
|
||||||
int major{ 0 };
|
int major{ 0 };
|
||||||
|
@ -80,6 +107,14 @@ public:
|
||||||
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
#endif // ENABLE_HACK_CLOSING_ON_OSX_10_9_5
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
enum class EMultisampleState : unsigned char
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Enabled,
|
||||||
|
Disabled
|
||||||
|
};
|
||||||
|
#else
|
||||||
enum EMultisampleState : unsigned char
|
enum EMultisampleState : unsigned char
|
||||||
{
|
{
|
||||||
MS_Unknown,
|
MS_Unknown,
|
||||||
|
@ -88,51 +123,85 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
|
typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
CanvasesMap m_canvases;
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
bool m_gl_initialized{ false };
|
||||||
|
wxGLContext* m_context{ nullptr };
|
||||||
|
#else
|
||||||
wxGLContext* m_context;
|
wxGLContext* m_context;
|
||||||
|
bool m_gl_initialized;
|
||||||
|
CanvasesMap m_canvases;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
static GLInfo s_gl_info;
|
static GLInfo s_gl_info;
|
||||||
#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
|
||||||
static OSInfo s_os_info;
|
static OSInfo 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
|
||||||
bool m_gl_initialized;
|
|
||||||
static EMultisampleState s_multisample;
|
|
||||||
static bool s_compressed_textures_supported;
|
static bool s_compressed_textures_supported;
|
||||||
|
static EMultisampleState s_multisample;
|
||||||
static EFramebufferType s_framebuffers_type;
|
static EFramebufferType s_framebuffers_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
GLCanvas3DManager() = default;
|
||||||
|
#else
|
||||||
GLCanvas3DManager();
|
GLCanvas3DManager();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
~GLCanvas3DManager();
|
~GLCanvas3DManager();
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
bool add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
|
bool add(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar);
|
||||||
bool remove(wxGLCanvas* canvas);
|
bool remove(wxGLCanvas* canvas);
|
||||||
void remove_all();
|
void remove_all();
|
||||||
|
|
||||||
unsigned int count() const;
|
size_t count() const;
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
bool init_gl();
|
||||||
|
#else
|
||||||
void init_gl();
|
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);
|
bool init(wxGLCanvas* canvas);
|
||||||
void destroy();
|
void destroy();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
GLCanvas3D* get_canvas(wxGLCanvas* canvas);
|
GLCanvas3D* get_canvas(wxGLCanvas* canvas);
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
static bool can_multisample() { return s_multisample == MS_Enabled; }
|
|
||||||
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
|
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); }
|
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; }
|
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);
|
static wxGLCanvas* create_wxglcanvas(wxWindow *parent);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
static const GLInfo& get_gl_info() { return s_gl_info; }
|
static const GLInfo& get_gl_info() { return s_gl_info; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
CanvasesMap::iterator do_get_canvas(wxGLCanvas* canvas);
|
CanvasesMap::iterator do_get_canvas(wxGLCanvas* canvas);
|
||||||
CanvasesMap::const_iterator do_get_canvas(wxGLCanvas* canvas) const;
|
CanvasesMap::const_iterator do_get_canvas(wxGLCanvas* canvas) const;
|
||||||
|
|
||||||
bool init(GLCanvas3D& canvas);
|
bool init(GLCanvas3D& canvas);
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
static void detect_multisample(int* attribList);
|
static void detect_multisample(int* attribList);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#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"
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
@ -35,13 +38,17 @@ namespace GUI {
|
||||||
|
|
||||||
m_state = Off;
|
m_state = Off;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
#else
|
||||||
const Camera& camera = canvas.get_camera();
|
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();
|
||||||
|
|
||||||
// bounding box created from the rectangle corners - will take care of order of the corners
|
// bounding box created from the rectangle corners - will take care of order of the corners
|
||||||
BoundingBox rectangle(Points{ Point(m_start_corner.cast<int>()), Point(m_end_corner.cast<int>()) });
|
BoundingBox rectangle(Points{ Point(m_start_corner.cast<coord_t>()), Point(m_end_corner.cast<coord_t>()) });
|
||||||
|
|
||||||
// Iterate over all points and determine whether they're in the rectangle.
|
// Iterate over all points and determine whether they're in the rectangle.
|
||||||
for (unsigned int i = 0; i<points.size(); ++i) {
|
for (unsigned int i = 0; i<points.size(); ++i) {
|
||||||
|
@ -68,7 +75,11 @@ namespace GUI {
|
||||||
if (!is_dragging())
|
if (!is_dragging())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
#else
|
||||||
const Camera& camera = canvas.get_camera();
|
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();
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#include "GLTexture.hpp"
|
#include "GLTexture.hpp"
|
||||||
|
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#include "GLCanvas3DManager.hpp"
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,14 @@
|
||||||
|
|
||||||
#include "GLToolbar.hpp"
|
#include "GLToolbar.hpp"
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
#include "slic3r/GUI/Camera.hpp"
|
||||||
|
#else
|
||||||
#include "../../slic3r/GUI/GLCanvas3D.hpp"
|
#include "../../slic3r/GUI/GLCanvas3D.hpp"
|
||||||
#include "../../slic3r/GUI/Camera.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>
|
||||||
|
@ -15,7 +21,6 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
|
||||||
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
|
||||||
|
@ -718,7 +723,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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();
|
||||||
|
@ -859,7 +868,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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();
|
||||||
|
@ -1008,7 +1021,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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();
|
||||||
|
@ -1081,7 +1098,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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();
|
||||||
|
@ -1233,7 +1254,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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;
|
||||||
|
@ -1281,7 +1306,11 @@ 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();
|
||||||
|
#else
|
||||||
float inv_zoom = (float)parent.get_camera().get_inv_zoom();
|
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;
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
#include "RemovableDriveManager.hpp"
|
#include "RemovableDriveManager.hpp"
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#include <Shlobj.h>
|
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
#include <shlobj.h>
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
||||||
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG
|
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG
|
||||||
|
@ -158,6 +158,41 @@ static void register_win32_device_notification_event()
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
wxWindow::MSWRegisterMessageHandler(MainFrame::WM_USER_MEDIACHANGED, [](wxWindow *win, WXUINT /* nMsg */, WXWPARAM wParam, WXLPARAM lParam) {
|
||||||
|
// Some messages are sent to top level windows by default, some messages are sent to only registered windows, and we explictely register on MainFrame only.
|
||||||
|
auto main_frame = dynamic_cast<MainFrame*>(win);
|
||||||
|
auto plater = (main_frame == nullptr) ? nullptr : main_frame->plater();
|
||||||
|
if (plater == nullptr)
|
||||||
|
// Maybe some other top level window like a dialog or maybe a pop-up menu?
|
||||||
|
return true;
|
||||||
|
wchar_t sPath[MAX_PATH];
|
||||||
|
if (lParam == SHCNE_MEDIAINSERTED || lParam == SHCNE_MEDIAREMOVED) {
|
||||||
|
struct _ITEMIDLIST* pidl = *reinterpret_cast<struct _ITEMIDLIST**>(wParam);
|
||||||
|
if (! SHGetPathFromIDList(pidl, sPath)) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "MediaInserted: SHGetPathFromIDList failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (lParam) {
|
||||||
|
case SHCNE_MEDIAINSERTED:
|
||||||
|
{
|
||||||
|
//printf("SHCNE_MEDIAINSERTED %S\n", sPath);
|
||||||
|
plater->GetEventHandler()->AddPendingEvent(VolumeAttachedEvent(EVT_VOLUME_ATTACHED));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SHCNE_MEDIAREMOVED:
|
||||||
|
{
|
||||||
|
//printf("SHCNE_MEDIAREMOVED %S\n", sPath);
|
||||||
|
plater->GetEventHandler()->AddPendingEvent(VolumeDetachedEvent(EVT_VOLUME_DETACHED));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// printf("Unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
@ -216,6 +251,23 @@ 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)
|
||||||
|
{
|
||||||
|
return GLCanvas3DManager::get_gl_info().to_string(format_as_html, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas)
|
||||||
|
{
|
||||||
|
return m_canvas_mgr.init_glcontext(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GUI_App::init_opengl()
|
||||||
|
{
|
||||||
|
return m_canvas_mgr.init_gl();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
bool GUI_App::OnInit()
|
bool GUI_App::OnInit()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -667,15 +719,16 @@ bool GUI_App::select_language()
|
||||||
// Try to load a new language.
|
// Try to load a new language.
|
||||||
if (index != -1 && (init_selection == -1 || init_selection != index)) {
|
if (index != -1 && (init_selection == -1 || init_selection != index)) {
|
||||||
const wxLanguageInfo *new_language_info = language_infos[index];
|
const wxLanguageInfo *new_language_info = language_infos[index];
|
||||||
if (new_language_info == m_language_info_best || new_language_info == m_language_info_system) {
|
|
||||||
// The newly selected profile matches user's default profile exactly. That's great.
|
|
||||||
} else if (m_language_info_best != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_'))
|
|
||||||
new_language_info = m_language_info_best;
|
|
||||||
else if (m_language_info_system != nullptr && new_language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_'))
|
|
||||||
new_language_info = m_language_info_system;
|
|
||||||
if (this->load_language(new_language_info->CanonicalName, false)) {
|
if (this->load_language(new_language_info->CanonicalName, false)) {
|
||||||
// Save language at application config.
|
// Save language at application config.
|
||||||
app_config->set("translation_language", m_wxLocale->GetCanonicalName().ToUTF8().data());
|
// Which language to save as the selected dictionary language?
|
||||||
|
// 1) Hopefully the language set to wxTranslations by this->load_language(), but that API is weird and we don't want to rely on its
|
||||||
|
// stability in the future:
|
||||||
|
// wxTranslations::Get()->GetBestTranslation(SLIC3R_APP_KEY, wxLANGUAGE_ENGLISH);
|
||||||
|
// 2) Current locale language may not match the dictionary name, see GH issue #3901
|
||||||
|
// m_wxLocale->GetCanonicalName()
|
||||||
|
// 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name.
|
||||||
|
app_config->set("translation_language", new_language_info->CanonicalName.ToUTF8().data());
|
||||||
app_config->save();
|
app_config->save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -704,7 +757,6 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||||
BOOST_LOG_TRIVIAL(trace) << boost::format("System language detected (user locales and such): %1%") % m_language_info_system->CanonicalName.ToUTF8().data();
|
BOOST_LOG_TRIVIAL(trace) << boost::format("System language detected (user locales and such): %1%") % m_language_info_system->CanonicalName.ToUTF8().data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(__WXMSW__) || defined(__WXOSX__)
|
|
||||||
{
|
{
|
||||||
// Allocating a temporary locale will switch the default wxTranslations to its internal wxTranslations instance.
|
// Allocating a temporary locale will switch the default wxTranslations to its internal wxTranslations instance.
|
||||||
wxLocale temp_locale;
|
wxLocale temp_locale;
|
||||||
|
@ -721,7 +773,6 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||||
BOOST_LOG_TRIVIAL(trace) << boost::format("Best translation language detected (may be different from user locales): %1%") % m_language_info_best->CanonicalName.ToUTF8().data();
|
BOOST_LOG_TRIVIAL(trace) << boost::format("Best translation language detected (may be different from user locales): %1%") % m_language_info_best->CanonicalName.ToUTF8().data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxLanguageInfo *language_info = language.empty() ? nullptr : wxLocale::FindLanguageInfo(language);
|
const wxLanguageInfo *language_info = language.empty() ? nullptr : wxLocale::FindLanguageInfo(language);
|
||||||
|
@ -737,6 +788,7 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (language_info == nullptr) {
|
if (language_info == nullptr) {
|
||||||
|
// PrusaSlicer does not support the Right to Left languages yet.
|
||||||
if (m_language_info_system != nullptr && m_language_info_system->LayoutDirection != wxLayout_RightToLeft)
|
if (m_language_info_system != nullptr && m_language_info_system->LayoutDirection != wxLayout_RightToLeft)
|
||||||
language_info = m_language_info_system;
|
language_info = m_language_info_system;
|
||||||
if (m_language_info_best != nullptr && m_language_info_best->LayoutDirection != wxLayout_RightToLeft)
|
if (m_language_info_best != nullptr && m_language_info_best->LayoutDirection != wxLayout_RightToLeft)
|
||||||
|
@ -755,6 +807,16 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Using Czech dictionaries for Slovak language";
|
BOOST_LOG_TRIVIAL(trace) << "Using Czech dictionaries for Slovak language";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select language for locales. This language may be different from the language of the dictionary.
|
||||||
|
if (language_info == m_language_info_best || language_info == m_language_info_system) {
|
||||||
|
// The current language matches user's default profile exactly. That's great.
|
||||||
|
} else if (m_language_info_best != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_best->CanonicalName.BeforeFirst('_')) {
|
||||||
|
// Use whatever the operating system recommends, if it the language code of the dictionary matches the recommended language.
|
||||||
|
// This allows a Swiss guy to use a German dictionary without forcing him to German locales.
|
||||||
|
language_info = m_language_info_best;
|
||||||
|
} else if (m_language_info_system != nullptr && language_info->CanonicalName.BeforeFirst('_') == m_language_info_system->CanonicalName.BeforeFirst('_'))
|
||||||
|
language_info = m_language_info_system;
|
||||||
|
|
||||||
if (! wxLocale::IsAvailable(language_info->Language)) {
|
if (! wxLocale::IsAvailable(language_info->Language)) {
|
||||||
// Loading the language dictionary failed.
|
// Loading the language dictionary failed.
|
||||||
wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed.";
|
wxString message = "Switching PrusaSlicer to language " + language_info->CanonicalName + " failed.";
|
||||||
|
@ -781,7 +843,7 @@ bool GUI_App::load_language(wxString language, bool initial)
|
||||||
wxTranslations::Get()->SetLanguage(language_dict);
|
wxTranslations::Get()->SetLanguage(language_dict);
|
||||||
m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
|
m_wxLocale->AddCatalog(SLIC3R_APP_KEY);
|
||||||
m_imgui->set_language(into_u8(language_info->CanonicalName));
|
m_imgui->set_language(into_u8(language_info->CanonicalName));
|
||||||
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
//FIXME This is a temporary workaround, the correct solution is to switch to "C" locale during file import / export only.
|
||||||
wxSetlocale(LC_NUMERIC, "C");
|
wxSetlocale(LC_NUMERIC, "C");
|
||||||
Preset::update_suffix_modified();
|
Preset::update_suffix_modified();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#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 "GLCanvas3DManager.hpp"
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
|
@ -96,7 +99,11 @@ 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;
|
||||||
|
|
||||||
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
GLCanvas3DManager m_canvas_mgr;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
|
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
|
||||||
|
|
||||||
std::unique_ptr<ImGuiWrapper> m_imgui;
|
std::unique_ptr<ImGuiWrapper> m_imgui;
|
||||||
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
std::unique_ptr<PrintHostJobQueue> m_printhost_job_queue;
|
||||||
|
@ -109,6 +116,12 @@ 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);
|
||||||
|
wxGLContext* init_glcontext(wxGLCanvas& canvas);
|
||||||
|
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();
|
||||||
void init_label_colours();
|
void init_label_colours();
|
||||||
|
|
|
@ -27,31 +27,63 @@
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||||
|
: m_canvas_widget(nullptr)
|
||||||
|
, m_canvas(nullptr)
|
||||||
|
{
|
||||||
|
init(parent, model, config, process);
|
||||||
|
}
|
||||||
|
#else
|
||||||
View3D::View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
View3D::View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||||
: m_canvas_widget(nullptr)
|
: m_canvas_widget(nullptr)
|
||||||
, m_canvas(nullptr)
|
, m_canvas(nullptr)
|
||||||
{
|
{
|
||||||
init(parent, bed, camera, view_toolbar, model, config, process);
|
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)
|
||||||
|
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);
|
_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;
|
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)
|
||||||
|
#else
|
||||||
bool View3D::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
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 = GLCanvas3DManager::create_wxglcanvas(*this);
|
||||||
|
if (m_canvas_widget == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_canvas = new GLCanvas3D(m_canvas_widget);
|
||||||
|
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
|
||||||
|
m_canvas->bind_event_handlers();
|
||||||
|
#else
|
||||||
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
|
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
|
||||||
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
|
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
|
||||||
m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
|
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(GLCanvas3DManager::can_multisample());
|
||||||
// XXX: If have OpenGL
|
// XXX: If have OpenGL
|
||||||
|
@ -66,6 +98,9 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_
|
||||||
m_canvas->enable_main_toolbar(true);
|
m_canvas->enable_main_toolbar(true);
|
||||||
m_canvas->enable_undoredo_toolbar(true);
|
m_canvas->enable_undoredo_toolbar(true);
|
||||||
m_canvas->enable_labels(true);
|
m_canvas->enable_labels(true);
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
m_canvas->enable_slope(true);
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
||||||
|
@ -163,6 +198,17 @@ void View3D::render()
|
||||||
m_canvas->set_as_dirty();
|
m_canvas->set_as_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
Preview::Preview(
|
||||||
|
wxWindow* parent, Model* model, DynamicPrintConfig* config,
|
||||||
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process_func)
|
||||||
|
#else
|
||||||
|
Preview::Preview(
|
||||||
|
wxWindow* parent, Model* model, DynamicPrintConfig* config,
|
||||||
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
#else
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
Preview::Preview(
|
Preview::Preview(
|
||||||
wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
||||||
|
@ -172,6 +218,7 @@ Preview::Preview(
|
||||||
wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
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)
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
#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)
|
||||||
|
@ -199,21 +246,39 @@ 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))
|
||||||
|
#else
|
||||||
if (init(parent, bed, camera, view_toolbar, model))
|
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)
|
||||||
|
#else
|
||||||
bool Preview::init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model)
|
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 = GLCanvas3DManager::create_wxglcanvas(*this);
|
||||||
|
if (m_canvas_widget == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_canvas = new GLCanvas3D(m_canvas_widget);
|
||||||
|
m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget));
|
||||||
|
m_canvas->bind_event_handlers();
|
||||||
|
#else
|
||||||
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
|
m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
|
||||||
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
|
_3DScene::add_canvas(m_canvas_widget, bed, camera, view_toolbar);
|
||||||
m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
|
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(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);
|
||||||
|
@ -322,9 +387,16 @@ Preview::~Preview()
|
||||||
{
|
{
|
||||||
unbind_event_handlers();
|
unbind_event_handlers();
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
if (m_canvas != nullptr)
|
||||||
|
delete m_canvas;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
if (m_canvas_widget != nullptr)
|
if (m_canvas_widget != nullptr)
|
||||||
{
|
{
|
||||||
_3DScene::remove_canvas(m_canvas_widget);
|
#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;
|
m_canvas = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ class GLCanvas3D;
|
||||||
class GLToolbar;
|
class GLToolbar;
|
||||||
class Bed3D;
|
class Bed3D;
|
||||||
struct Camera;
|
struct Camera;
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
class Plater;
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
class View3D : public wxPanel
|
class View3D : public wxPanel
|
||||||
{
|
{
|
||||||
|
@ -44,7 +47,11 @@ 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);
|
||||||
|
#else
|
||||||
View3D(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
|
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; }
|
||||||
|
@ -72,7 +79,11 @@ public:
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
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);
|
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
|
||||||
|
@ -115,6 +126,15 @@ class Preview : public wxPanel
|
||||||
DoubleSlider::Control* m_slider {nullptr};
|
DoubleSlider::Control* m_slider {nullptr};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
|
||||||
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
|
||||||
|
#else
|
||||||
|
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
|
||||||
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = []() {});
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
#else
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
||||||
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
|
||||||
|
@ -122,6 +142,7 @@ public:
|
||||||
Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config,
|
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 = []() {});
|
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = []() {});
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
virtual ~Preview();
|
virtual ~Preview();
|
||||||
|
|
||||||
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
|
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
|
||||||
|
@ -148,7 +169,11 @@ 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);
|
||||||
|
#else
|
||||||
bool init(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model);
|
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();
|
||||||
|
@ -181,7 +206,6 @@ private:
|
||||||
void load_print_as_sla();
|
void load_print_as_sla();
|
||||||
|
|
||||||
void on_sliders_scroll_changed(wxCommandEvent& event);
|
void on_sliders_scroll_changed(wxCommandEvent& event);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
#include "slic3r/GUI/MeshUtils.hpp"
|
#include "slic3r/GUI/MeshUtils.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#include "slic3r/GUI/Camera.hpp"
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
#include "slic3r/GUI/PresetBundle.hpp"
|
#include "slic3r/GUI/PresetBundle.hpp"
|
||||||
#include "libslic3r/SLAPrint.hpp"
|
#include "libslic3r/SLAPrint.hpp"
|
||||||
#include "libslic3r/TriangleMesh.hpp"
|
#include "libslic3r/TriangleMesh.hpp"
|
||||||
|
@ -311,7 +314,11 @@ bool GLGizmoHollow::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, V
|
||||||
if (! m_c->m_mesh_raycaster)
|
if (! m_c->m_mesh_raycaster)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
#else
|
||||||
const Camera& camera = m_parent.get_camera();
|
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();
|
||||||
|
@ -426,7 +433,11 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
||||||
points_inside.push_back(points[idx].cast<float>());
|
points_inside.push_back(points[idx].cast<float>());
|
||||||
|
|
||||||
// Only select/deselect points that are actually visible
|
// Only select/deselect points that are actually visible
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, wxGetApp().plater()->get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
||||||
|
#else
|
||||||
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
{
|
{
|
||||||
if (rectangle_status == GLSelectionRectangle::Deselect)
|
if (rectangle_status == GLSelectionRectangle::Deselect)
|
||||||
unselect_point(points_idxs[idx]);
|
unselect_point(points_idxs[idx]);
|
||||||
|
@ -1026,8 +1037,13 @@ void GLGizmoHollow::update_clipping_plane(bool keep_normal) const
|
||||||
{
|
{
|
||||||
if (! m_c->m_model_object)
|
if (! m_c->m_model_object)
|
||||||
return;
|
return;
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
||||||
|
m_c->m_clipping_plane->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward());
|
||||||
|
#else
|
||||||
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
||||||
m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
|
m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
|
const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
|
||||||
float dist = normal.dot(center);
|
float dist = normal.dot(center);
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include "slic3r/GUI/GUI.hpp"
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
#include "slic3r/GUI/GUI_ObjectSettings.hpp"
|
#include "slic3r/GUI/GUI_ObjectSettings.hpp"
|
||||||
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#include "slic3r/GUI/Camera.hpp"
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
#include "slic3r/GUI/MeshUtils.hpp"
|
#include "slic3r/GUI/MeshUtils.hpp"
|
||||||
#include "slic3r/GUI/Plater.hpp"
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
#include "slic3r/GUI/PresetBundle.hpp"
|
#include "slic3r/GUI/PresetBundle.hpp"
|
||||||
|
@ -379,7 +382,11 @@ bool GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec
|
||||||
if (! m_c->m_mesh_raycaster)
|
if (! m_c->m_mesh_raycaster)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
#else
|
||||||
const Camera& camera = m_parent.get_camera();
|
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();
|
||||||
|
@ -489,7 +496,11 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||||
points_inside.push_back(points[idx].cast<float>());
|
points_inside.push_back(points[idx].cast<float>());
|
||||||
|
|
||||||
// Only select/deselect points that are actually visible
|
// Only select/deselect points that are actually visible
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, wxGetApp().plater()->get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
||||||
|
#else
|
||||||
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
for (size_t idx : m_c->m_mesh_raycaster->get_unobscured_idxs(trafo, m_parent.get_camera(), points_inside, m_c->m_clipping_plane.get()))
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
{
|
{
|
||||||
if (rectangle_status == GLSelectionRectangle::Deselect)
|
if (rectangle_status == GLSelectionRectangle::Deselect)
|
||||||
unselect_point(points_idxs[idx]);
|
unselect_point(points_idxs[idx]);
|
||||||
|
@ -1282,8 +1293,14 @@ void GLGizmoSlaSupports::update_clipping_plane(bool keep_normal) const
|
||||||
{
|
{
|
||||||
if (! m_c->m_model_object)
|
if (! m_c->m_model_object)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
||||||
m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
|
m_c->m_clipping_plane->get_normal() : -wxGetApp().plater()->get_camera().get_dir_forward());
|
||||||
|
#else
|
||||||
|
Vec3d normal = (keep_normal && m_c->m_clipping_plane->get_normal() != Vec3d::Zero() ?
|
||||||
|
m_c->m_clipping_plane->get_normal() : -m_parent.get_camera().get_dir_forward());
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
|
const Vec3d& center = m_c->m_model_object->instances[m_c->m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift);
|
||||||
float dist = normal.dot(center);
|
float dist = normal.dot(center);
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#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"
|
||||||
|
#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"
|
||||||
|
@ -1029,8 +1032,13 @@ 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 inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
|
||||||
|
#else
|
||||||
float zoom = (float)m_parent.get_camera().get_zoom();
|
float zoom = (float)m_parent.get_camera().get_zoom();
|
||||||
float inv_zoom = (float)m_parent.get_camera().get_inv_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();
|
||||||
|
@ -1081,7 +1089,11 @@ 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();
|
||||||
|
#else
|
||||||
float toolbar_top = cnv_h - m_parent.get_view_toolbar_height();
|
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;
|
||||||
|
|
|
@ -145,6 +145,9 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||||
// View
|
// View
|
||||||
{ "0-6", L("Camera view") },
|
{ "0-6", L("Camera view") },
|
||||||
{ "E", L("Show/Hide object/instance labels") },
|
{ "E", L("Show/Hide object/instance labels") },
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
{ "D", L("Turn On/Off facets' slope rendering") },
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
// Configuration
|
// Configuration
|
||||||
{ ctrl + "P", L("Preferences") },
|
{ ctrl + "P", L("Preferences") },
|
||||||
// Help
|
// Help
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
#include <shlobj.h>
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
@ -127,6 +128,30 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
// DEV_BROADCAST_HANDLE NotificationFilter = { 0 };
|
// DEV_BROADCAST_HANDLE NotificationFilter = { 0 };
|
||||||
// NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
|
// NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
|
||||||
// NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
|
// NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
|
||||||
|
|
||||||
|
// Using Win32 Shell API to register for media insert / removal events.
|
||||||
|
LPITEMIDLIST ppidl;
|
||||||
|
if (SHGetSpecialFolderLocation(this->GetHWND(), CSIDL_DESKTOP, &ppidl) == NOERROR) {
|
||||||
|
SHChangeNotifyEntry shCNE;
|
||||||
|
shCNE.pidl = ppidl;
|
||||||
|
shCNE.fRecursive = TRUE;
|
||||||
|
// Returns a positive integer registration identifier (ID).
|
||||||
|
// Returns zero if out of memory or in response to invalid parameters.
|
||||||
|
m_ulSHChangeNotifyRegister = SHChangeNotifyRegister(this->GetHWND(), // Hwnd to receive notification
|
||||||
|
SHCNE_DISKEVENTS, // Event types of interest (sources)
|
||||||
|
SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED,
|
||||||
|
//SHCNE_UPDATEITEM, // Events of interest - use SHCNE_ALLEVENTS for all events
|
||||||
|
WM_USER_MEDIACHANGED, // Notification message to be sent upon the event
|
||||||
|
1, // Number of entries in the pfsne array
|
||||||
|
&shCNE); // Array of SHChangeNotifyEntry structures that
|
||||||
|
// contain the notifications. This array should
|
||||||
|
// always be set to one when calling SHChnageNotifyRegister
|
||||||
|
// or SHChangeNotifyDeregister will not work properly.
|
||||||
|
assert(m_ulSHChangeNotifyRegister != 0); // Shell notification failed
|
||||||
|
} else {
|
||||||
|
// Failed to get desktop location
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
// propagate event
|
// propagate event
|
||||||
|
@ -161,13 +186,26 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
|
||||||
void MainFrame::shutdown()
|
void MainFrame::shutdown()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::UnregisterDeviceNotification(HDEVNOTIFY(m_hDeviceNotify));
|
if (m_hDeviceNotify) {
|
||||||
m_hDeviceNotify = nullptr;
|
::UnregisterDeviceNotification(HDEVNOTIFY(m_hDeviceNotify));
|
||||||
|
m_hDeviceNotify = nullptr;
|
||||||
|
}
|
||||||
|
if (m_ulSHChangeNotifyRegister) {
|
||||||
|
SHChangeNotifyDeregister(m_ulSHChangeNotifyRegister);
|
||||||
|
m_ulSHChangeNotifyRegister = 0;
|
||||||
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
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,
|
||||||
|
// when closing the application using Command+Q, a mouse event is triggered after this lambda is completed,
|
||||||
|
// causing a crash
|
||||||
|
if (m_plater) m_plater->unbind_canvas_event_handlers();
|
||||||
|
#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.
|
||||||
// Also the application closes much faster without these unnecessary screen refreshes.
|
// Also the application closes much faster without these unnecessary screen refreshes.
|
||||||
|
@ -188,7 +226,9 @@ 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();
|
_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
|
||||||
|
@ -214,7 +254,8 @@ void MainFrame::update_title()
|
||||||
if (idx_plus != build_id.npos) {
|
if (idx_plus != build_id.npos) {
|
||||||
// Parse what is behind the '+'. If there is a number, then it is a build number after the label, and full build ID is shown.
|
// Parse what is behind the '+'. If there is a number, then it is a build number after the label, and full build ID is shown.
|
||||||
int commit_after_label;
|
int commit_after_label;
|
||||||
if (! boost::starts_with(build_id.data() + idx_plus + 1, "UNKNOWN") && sscanf(build_id.data() + idx_plus + 1, "%d-", &commit_after_label) == 0) {
|
if (! boost::starts_with(build_id.data() + idx_plus + 1, "UNKNOWN") &&
|
||||||
|
(build_id.at(idx_plus + 1) == '-' || sscanf(build_id.data() + idx_plus + 1, "%d-", &commit_after_label) == 0)) {
|
||||||
// It is a release build.
|
// It is a release build.
|
||||||
build_id.erase(build_id.begin() + idx_plus, build_id.end());
|
build_id.erase(build_id.begin() + idx_plus, build_id.end());
|
||||||
#if defined(_WIN32) && ! defined(_WIN64)
|
#if defined(_WIN32) && ! defined(_WIN64)
|
||||||
|
@ -754,9 +795,20 @@ void MainFrame::init_menubar()
|
||||||
append_menu_item(viewMenu, wxID_ANY, _(L("Right")) + sep + "&6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); },
|
append_menu_item(viewMenu, wxID_ANY, _(L("Right")) + sep + "&6", _(L("Right View")), [this](wxCommandEvent&) { select_view("right"); },
|
||||||
"", nullptr, [this](){return can_change_view(); }, this);
|
"", nullptr, [this](){return can_change_view(); }, this);
|
||||||
viewMenu->AppendSeparator();
|
viewMenu->AppendSeparator();
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
wxMenu* options_menu = new wxMenu();
|
||||||
|
append_menu_check_item(options_menu, wxID_ANY, _(L("Show &labels")) + sep + "E", _(L("Show object/instance labels in 3D scene")),
|
||||||
|
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
|
||||||
|
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
|
||||||
|
append_menu_check_item(options_menu, wxID_ANY, _(L("Show &slope")) + sep + "D", _(L("Objects coloring using faces' slope")),
|
||||||
|
[this](wxCommandEvent&) { m_plater->show_view3D_slope(!m_plater->is_view3D_slope_shown()); }, this,
|
||||||
|
[this]() { return m_plater->is_view3D_shown() && !m_plater->is_view3D_layers_editing_enabled(); }, [this]() { return m_plater->is_view3D_slope_shown(); }, this);
|
||||||
|
append_submenu(viewMenu, options_menu, wxID_ANY, _(L("&Options")), "");
|
||||||
|
#else
|
||||||
append_menu_check_item(viewMenu, wxID_ANY, _(L("Show &labels")) + sep + "E", _(L("Show object/instance labels in 3D scene")),
|
append_menu_check_item(viewMenu, wxID_ANY, _(L("Show &labels")) + sep + "E", _(L("Show object/instance labels in 3D scene")),
|
||||||
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
|
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
|
||||||
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
|
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
}
|
}
|
||||||
|
|
||||||
// Help menu
|
// Help menu
|
||||||
|
|
|
@ -144,6 +144,8 @@ public:
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* m_hDeviceNotify { nullptr };
|
void* m_hDeviceNotify { nullptr };
|
||||||
|
uint32_t m_ulSHChangeNotifyRegister { 0 };
|
||||||
|
static constexpr int WM_USER_MEDIACHANGED { 0x7FFF }; // WM_USER from 0x0400 to 0x7FFF, picking the last one to not interfere with wxWidgets allocation
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,11 @@
|
||||||
#include "../Utils/FixModelByWin10.hpp"
|
#include "../Utils/FixModelByWin10.hpp"
|
||||||
#include "../Utils/UndoRedo.hpp"
|
#include "../Utils/UndoRedo.hpp"
|
||||||
#include "RemovableDriveManager.hpp"
|
#include "RemovableDriveManager.hpp"
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "Gizmos/GLGizmosManager.hpp"
|
||||||
|
#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"
|
||||||
|
@ -1821,8 +1826,18 @@ struct Plater::priv
|
||||||
bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); }
|
bool are_view3D_labels_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->are_labels_shown(); }
|
||||||
void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); }
|
void show_view3D_labels(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_labels(show); }
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
bool is_view3D_slope_shown() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_slope_shown(); }
|
||||||
|
void show_view3D_slope(bool show) { if (current_panel == view3D) view3D->get_canvas3d()->show_slope(show); }
|
||||||
|
|
||||||
|
bool is_view3D_layers_editing_enabled() const { return (current_panel == view3D) && view3D->get_canvas3d()->is_layers_editing_enabled(); }
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
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();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
bool init_view_toolbar();
|
bool init_view_toolbar();
|
||||||
|
|
||||||
|
@ -2054,12 +2069,26 @@ 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);
|
||||||
|
#if ENABLE_GCODE_VIEWER
|
||||||
|
preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, &gcode_result, [this]() { schedule_background_process(); });
|
||||||
|
#else
|
||||||
|
preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); });
|
||||||
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
|
||||||
|
view_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size);
|
||||||
|
#endif // __APPLE__
|
||||||
|
#else
|
||||||
view3D = new View3D(q, bed, camera, view_toolbar, &model, config, &background_process);
|
view3D = new View3D(q, bed, camera, view_toolbar, &model, config, &background_process);
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, &gcode_result, [this]() { schedule_background_process(); });
|
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, &gcode_result, [this]() { schedule_background_process(); });
|
||||||
#else
|
#else
|
||||||
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
|
preview = new Preview(q, bed, camera, view_toolbar, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); });
|
||||||
#endif // ENABLE_GCODE_VIEWER
|
#endif // ENABLE_GCODE_VIEWER
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
panels.push_back(view3D);
|
panels.push_back(view3D);
|
||||||
panels.push_back(preview);
|
panels.push_back(preview);
|
||||||
|
@ -2159,7 +2188,9 @@ 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();
|
update_ui_from_settings();
|
||||||
|
#endif // !ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
q->Layout();
|
q->Layout();
|
||||||
|
|
||||||
set_current_panel(view3D);
|
set_current_panel(view3D);
|
||||||
|
@ -4058,6 +4089,17 @@ 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()
|
||||||
|
{
|
||||||
|
if (view3D != nullptr)
|
||||||
|
view3D->get_canvas3d()->unbind_event_handlers();
|
||||||
|
|
||||||
|
if (preview != nullptr)
|
||||||
|
preview->get_canvas3d()->unbind_event_handlers();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
bool Plater::priv::init_view_toolbar()
|
bool Plater::priv::init_view_toolbar()
|
||||||
{
|
{
|
||||||
if (view_toolbar.get_items_count() > 0)
|
if (view_toolbar.get_items_count() > 0)
|
||||||
|
@ -4528,7 +4570,8 @@ void Sidebar::set_btn_label(const ActionButtonType btn_type, const wxString& lab
|
||||||
// Plater / Public
|
// Plater / Public
|
||||||
|
|
||||||
Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
Plater::Plater(wxWindow *parent, MainFrame *main_frame)
|
||||||
: wxPanel(parent), p(new priv(this, main_frame))
|
: wxPanel(parent)
|
||||||
|
, p(new priv(this, main_frame))
|
||||||
{
|
{
|
||||||
// Initialization performed in the private c-tor
|
// Initialization performed in the private c-tor
|
||||||
}
|
}
|
||||||
|
@ -4652,6 +4695,13 @@ bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); }
|
||||||
bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown(); }
|
bool Plater::are_view3D_labels_shown() const { return p->are_view3D_labels_shown(); }
|
||||||
void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); }
|
void Plater::show_view3D_labels(bool show) { p->show_view3D_labels(show); }
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
bool Plater::is_view3D_slope_shown() const { return p->is_view3D_slope_shown(); }
|
||||||
|
void Plater::show_view3D_slope(bool show) { p->show_view3D_slope(show); }
|
||||||
|
|
||||||
|
bool Plater::is_view3D_layers_editing_enabled() const { return p->is_view3D_layers_editing_enabled(); }
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
void Plater::select_all() { p->select_all(); }
|
void Plater::select_all() { p->select_all(); }
|
||||||
void Plater::deselect_all() { p->deselect_all(); }
|
void Plater::deselect_all() { p->deselect_all(); }
|
||||||
|
|
||||||
|
@ -5459,6 +5509,13 @@ 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()
|
||||||
|
{
|
||||||
|
p->unbind_canvas_event_handlers();
|
||||||
|
}
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
PrinterTechnology Plater::printer_technology() const
|
PrinterTechnology Plater::printer_technology() const
|
||||||
{
|
{
|
||||||
return p->printer_technology;
|
return p->printer_technology;
|
||||||
|
@ -5592,6 +5649,28 @@ Camera& Plater::get_camera()
|
||||||
return p->camera;
|
return p->camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
const Bed3D& Plater::get_bed() const
|
||||||
|
{
|
||||||
|
return p->bed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bed3D& Plater::get_bed()
|
||||||
|
{
|
||||||
|
return p->bed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GLToolbar& Plater::get_view_toolbar() const
|
||||||
|
{
|
||||||
|
return p->view_toolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLToolbar& Plater::get_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
|
||||||
{
|
{
|
||||||
return p->mouse3d_controller;
|
return p->mouse3d_controller;
|
||||||
|
|
|
@ -42,6 +42,10 @@ class ObjectList;
|
||||||
class GLCanvas3D;
|
class GLCanvas3D;
|
||||||
class Mouse3DController;
|
class Mouse3DController;
|
||||||
struct Camera;
|
struct Camera;
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
class Bed3D;
|
||||||
|
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>>;
|
||||||
|
|
||||||
|
@ -171,6 +175,13 @@ public:
|
||||||
bool are_view3D_labels_shown() const;
|
bool are_view3D_labels_shown() const;
|
||||||
void show_view3D_labels(bool show);
|
void show_view3D_labels(bool show);
|
||||||
|
|
||||||
|
#if ENABLE_SLOPE_RENDERING
|
||||||
|
bool is_view3D_slope_shown() const;
|
||||||
|
void show_view3D_slope(bool show);
|
||||||
|
|
||||||
|
bool is_view3D_layers_editing_enabled() const;
|
||||||
|
#endif // ENABLE_SLOPE_RENDERING
|
||||||
|
|
||||||
// Called after the Preferences dialog is closed and the program settings are saved.
|
// Called after the Preferences dialog is closed and the program settings are saved.
|
||||||
// Update the UI based on the current preferences.
|
// Update the UI based on the current preferences.
|
||||||
void update_ui_from_settings();
|
void update_ui_from_settings();
|
||||||
|
@ -249,6 +260,9 @@ public:
|
||||||
BoundingBoxf bed_shape_bb() const;
|
BoundingBoxf bed_shape_bb() const;
|
||||||
|
|
||||||
void set_current_canvas_as_dirty();
|
void set_current_canvas_as_dirty();
|
||||||
|
#if ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
void unbind_canvas_event_handlers();
|
||||||
|
#endif // ENABLE_NON_STATIC_CANVAS_MANAGER
|
||||||
|
|
||||||
PrinterTechnology printer_technology() const;
|
PrinterTechnology printer_technology() const;
|
||||||
void set_printer_technology(PrinterTechnology printer_technology);
|
void set_printer_technology(PrinterTechnology printer_technology);
|
||||||
|
@ -278,12 +292,21 @@ 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;
|
||||||
|
Bed3D& get_bed();
|
||||||
|
|
||||||
|
const GLToolbar& get_view_toolbar() const;
|
||||||
|
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();
|
||||||
|
|
||||||
void set_bed_shape() const;
|
void set_bed_shape() const;
|
||||||
|
|
||||||
// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
|
// ROII wrapper for suppressing the Undo / Redo snapshot to be taken.
|
||||||
class SuppressSnapshots
|
class SuppressSnapshots
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -33,17 +33,19 @@ wxDEFINE_EVENT(EVT_REMOVABLE_DRIVES_CHANGED, RemovableDrivesChangedEvent);
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() const
|
std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() const
|
||||||
{
|
{
|
||||||
//get logical drives flags by letter in alphabetical order
|
// Get logical drives flags by letter in alphabetical order.
|
||||||
DWORD drives_mask = ::GetLogicalDrives();
|
DWORD drives_mask = ::GetLogicalDrives();
|
||||||
|
|
||||||
// Allocate the buffers before the loop.
|
// Allocate the buffers before the loop.
|
||||||
std::wstring volume_name;
|
std::wstring volume_name;
|
||||||
std::wstring file_system_name;
|
std::wstring file_system_name;
|
||||||
// Iterate the Windows drives from 'A' to 'Z'
|
// Iterate the Windows drives from 'C' to 'Z'
|
||||||
std::vector<DriveData> current_drives;
|
std::vector<DriveData> current_drives;
|
||||||
for (size_t i = 0; i < 26; ++ i)
|
// Skip A and B drives.
|
||||||
if (drives_mask & (1 << i)) {
|
drives_mask >>= 2;
|
||||||
std::string path { char('A' + i), ':' };
|
for (char drive = 'C'; drive <= 'Z'; ++ drive, drives_mask >>= 1)
|
||||||
|
if (drives_mask & 1) {
|
||||||
|
std::string path { drive, ':' };
|
||||||
UINT drive_type = ::GetDriveTypeA(path.c_str());
|
UINT drive_type = ::GetDriveTypeA(path.c_str());
|
||||||
// DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives)
|
// DRIVE_REMOVABLE on W are sd cards and usb thumbnails (not usb harddrives)
|
||||||
if (drive_type == DRIVE_REMOVABLE) {
|
if (drive_type == DRIVE_REMOVABLE) {
|
||||||
|
@ -450,14 +452,8 @@ void RemovableDriveManager::thread_proc()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lck(m_thread_stop_mutex);
|
std::unique_lock<std::mutex> lck(m_thread_stop_mutex);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Windows do not send an update on insert / eject of an SD card into an external SD card reader.
|
// Reacting to updates by WM_DEVICECHANGE and WM_USER_MEDIACHANGED
|
||||||
// Windows also do not send an update on software eject of a FLASH drive.
|
m_thread_stop_condition.wait(lck, [this]{ return m_stop || m_wakeup; });
|
||||||
// We can likely use the Windows WMI API, but it will be quite time consuming to implement.
|
|
||||||
// https://www.codeproject.com/Articles/10539/Making-WMI-Queries-In-C
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-start-page
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/com-api-for-wmi
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/example--receiving-event-notifications-through-wmi-
|
|
||||||
m_thread_stop_condition.wait_for(lck, std::chrono::seconds(2), [this]{ return m_stop || m_wakeup; });
|
|
||||||
#else
|
#else
|
||||||
m_thread_stop_condition.wait_for(lck, std::chrono::seconds(2), [this]{ return m_stop; });
|
m_thread_stop_condition.wait_for(lck, std::chrono::seconds(2), [this]{ return m_stop; });
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -440,6 +440,12 @@ 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
|
||||||
|
if (wxGetApp().obj_manipul() == nullptr)
|
||||||
|
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();
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,11 @@ 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));
|
||||||
|
#else
|
||||||
get_mem_info(true) + "<br>" + _3DScene::get_gl_info(true, true));
|
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);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +202,11 @@ 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);
|
||||||
|
#else
|
||||||
const auto text = get_main_info(false)+"\n"+_3DScene::get_gl_info(false, true);
|
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();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -18,8 +18,8 @@ using namespace std;
|
||||||
|
|
||||||
SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||||
GIVEN( "A 20mm cube, built from constexpr std::array" ) {
|
GIVEN( "A 20mm cube, built from constexpr std::array" ) {
|
||||||
std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
|
||||||
|
@ -68,8 +68,8 @@ SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||||
|
|
||||||
}
|
}
|
||||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
@ -121,8 +121,8 @@ SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||||
|
|
||||||
SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
|
SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
|
||||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
|
||||||
|
@ -184,8 +184,8 @@ SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
|
||||||
|
|
||||||
SCENARIO( "TriangleMesh: slice behavior.") {
|
SCENARIO( "TriangleMesh: slice behavior.") {
|
||||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
|
||||||
|
@ -205,8 +205,8 @@ SCENARIO( "TriangleMesh: slice behavior.") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GIVEN( "A STL with an irregular shape.") {
|
GIVEN( "A STL with an irregular shape.") {
|
||||||
const std::vector<Vec3d> vertices {Vec3d(0,0,0),Vec3d(0,0,20),Vec3d(0,5,0),Vec3d(0,5,20),Vec3d(50,0,0),Vec3d(50,0,20),Vec3d(15,5,0),Vec3d(35,5,0),Vec3d(15,20,0),Vec3d(50,5,0),Vec3d(35,20,0),Vec3d(15,5,10),Vec3d(50,5,20),Vec3d(35,5,10),Vec3d(35,20,10),Vec3d(15,20,10)};
|
const std::vector<Vec3d> vertices {{0,0,0},{0,0,20},{0,5,0},{0,5,20},{50,0,0},{50,0,20},{15,5,0},{35,5,0},{15,20,0},{50,5,0},{35,20,0},{15,5,10},{50,5,20},{35,5,10},{35,20,10},{15,20,10}};
|
||||||
const std::vector<Vec3crd> facets {Vec3crd(0,1,2),Vec3crd(2,1,3),Vec3crd(1,0,4),Vec3crd(5,1,4),Vec3crd(0,2,4),Vec3crd(4,2,6),Vec3crd(7,6,8),Vec3crd(4,6,7),Vec3crd(9,4,7),Vec3crd(7,8,10),Vec3crd(2,3,6),Vec3crd(11,3,12),Vec3crd(7,12,9),Vec3crd(13,12,7),Vec3crd(6,3,11),Vec3crd(11,12,13),Vec3crd(3,1,5),Vec3crd(12,3,5),Vec3crd(5,4,9),Vec3crd(12,5,9),Vec3crd(13,7,10),Vec3crd(14,13,10),Vec3crd(8,15,10),Vec3crd(10,15,14),Vec3crd(6,11,8),Vec3crd(8,11,15),Vec3crd(15,11,13),Vec3crd(14,15,13)};
|
const std::vector<Vec3i> facets {{0,1,2},{2,1,3},{1,0,4},{5,1,4},{0,2,4},{4,2,6},{7,6,8},{4,6,7},{9,4,7},{7,8,10},{2,3,6},{11,3,12},{7,12,9},{13,12,7},{6,3,11},{11,12,13},{3,1,5},{12,3,5},{5,4,9},{12,5,9},{13,7,10},{14,13,10},{8,15,10},{10,15,14},{6,11,8},{8,11,15},{15,11,13},{14,15,13}};
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
@ -294,8 +294,8 @@ SCENARIO( "make_xxx functions produce meshes.") {
|
||||||
|
|
||||||
SCENARIO( "TriangleMesh: split functionality.") {
|
SCENARIO( "TriangleMesh: split functionality.") {
|
||||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
@ -308,8 +308,8 @@ SCENARIO( "TriangleMesh: split functionality.") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GIVEN( "Two 20mm cubes, each with one corner on the origin, merged into a single TriangleMesh") {
|
GIVEN( "Two 20mm cubes, each with one corner on the origin, merged into a single TriangleMesh") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
@ -329,8 +329,8 @@ SCENARIO( "TriangleMesh: split functionality.") {
|
||||||
|
|
||||||
SCENARIO( "TriangleMesh: Mesh merge functions") {
|
SCENARIO( "TriangleMesh: Mesh merge functions") {
|
||||||
GIVEN( "Two 20mm cubes, each with one corner on the origin") {
|
GIVEN( "Two 20mm cubes, each with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
@ -349,8 +349,8 @@ SCENARIO( "TriangleMesh: Mesh merge functions") {
|
||||||
|
|
||||||
SCENARIO( "TriangleMeshSlicer: Cut behavior.") {
|
SCENARIO( "TriangleMeshSlicer: Cut behavior.") {
|
||||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
const std::vector<Vec3d> vertices { {20,20,0}, {20,0,0}, {0,0,0}, {0,20,0}, {20,20,20}, {0,20,20}, {0,0,20}, {20,0,20} };
|
||||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
const std::vector<Vec3i> facets { {0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {0,4,7}, {0,7,1}, {1,7,6}, {1,6,2}, {2,6,5}, {2,5,3}, {4,0,3}, {4,3,5} };
|
||||||
|
|
||||||
TriangleMesh cube(vertices, facets);
|
TriangleMesh cube(vertices, facets);
|
||||||
cube.repair();
|
cube.repair();
|
||||||
|
|
|
@ -15,7 +15,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
|
||||||
coord_t s = 1000000;
|
coord_t s = 1000000;
|
||||||
GIVEN("20mm box") {
|
GIVEN("20mm box") {
|
||||||
ExPolygon box20mm;
|
ExPolygon box20mm;
|
||||||
box20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 20 * s, 20 * s}, { 0, 20 * s} };
|
box20mm.contour.points = { Vec2crd{ 0, 0 }, Vec2crd{ 20 * s, 0 }, Vec2crd{ 20 * s, 20 * s}, Vec2crd{ 0, 20 * s} };
|
||||||
std::vector<float> deltas_plus(box20mm.contour.points.size(), 1. * s);
|
std::vector<float> deltas_plus(box20mm.contour.points.size(), 1. * s);
|
||||||
std::vector<float> deltas_minus(box20mm.contour.points.size(), - 1. * s);
|
std::vector<float> deltas_minus(box20mm.contour.points.size(), - 1. * s);
|
||||||
Polygons output;
|
Polygons output;
|
||||||
|
@ -87,8 +87,8 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
|
||||||
|
|
||||||
GIVEN("20mm box with 10mm hole") {
|
GIVEN("20mm box with 10mm hole") {
|
||||||
ExPolygon box20mm;
|
ExPolygon box20mm;
|
||||||
box20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 20 * s, 20 * s}, { 0, 20 * s} };
|
box20mm.contour.points = { Vec2crd{ 0, 0 }, Vec2crd{ 20 * s, 0 }, Vec2crd{ 20 * s, 20 * s}, Vec2crd{ 0, 20 * s} };
|
||||||
box20mm.holes.emplace_back(Slic3r::Polygon({ { 5 * s, 5 * s }, { 5 * s, 15 * s}, { 15 * s, 15 * s}, { 15 * s, 5 * s } }));
|
box20mm.holes.emplace_back(Slic3r::Polygon({ Vec2crd{ 5 * s, 5 * s }, Vec2crd{ 5 * s, 15 * s}, Vec2crd{ 15 * s, 15 * s}, Vec2crd{ 15 * s, 5 * s } }));
|
||||||
std::vector<float> deltas_plus(box20mm.contour.points.size(), 1. * s);
|
std::vector<float> deltas_plus(box20mm.contour.points.size(), 1. * s);
|
||||||
std::vector<float> deltas_minus(box20mm.contour.points.size(), -1. * s);
|
std::vector<float> deltas_minus(box20mm.contour.points.size(), -1. * s);
|
||||||
ExPolygons output;
|
ExPolygons output;
|
||||||
|
@ -164,7 +164,7 @@ SCENARIO("Constant offset", "[ClipperUtils]") {
|
||||||
|
|
||||||
GIVEN("20mm right angle triangle") {
|
GIVEN("20mm right angle triangle") {
|
||||||
ExPolygon triangle20mm;
|
ExPolygon triangle20mm;
|
||||||
triangle20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 0, 20 * s} };
|
triangle20mm.contour.points = { Vec2crd{ 0, 0 }, Vec2crd{ 20 * s, 0 }, Vec2crd{ 0, 20 * s } };
|
||||||
Polygons output;
|
Polygons output;
|
||||||
double offset = 1.;
|
double offset = 1.;
|
||||||
// Angle of the sharp corner bisector.
|
// Angle of the sharp corner bisector.
|
||||||
|
|
|
@ -246,7 +246,7 @@ TEST_CASE("Traversing Clipper PolyTree", "[ClipperUtils]") {
|
||||||
// Create a polygon representing unit box
|
// Create a polygon representing unit box
|
||||||
Polygon unitbox;
|
Polygon unitbox;
|
||||||
const auto UNIT = coord_t(1. / SCALING_FACTOR);
|
const auto UNIT = coord_t(1. / SCALING_FACTOR);
|
||||||
unitbox.points = {{0, 0}, {UNIT, 0}, {UNIT, UNIT}, {0, UNIT}};
|
unitbox.points = { Vec2crd{0, 0}, Vec2crd{UNIT, 0}, Vec2crd{UNIT, UNIT}, Vec2crd{0, UNIT}};
|
||||||
|
|
||||||
Polygon box_frame = unitbox;
|
Polygon box_frame = unitbox;
|
||||||
box_frame.scale(20, 10);
|
box_frame.scale(20, 10);
|
||||||
|
|
|
@ -519,7 +519,7 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") {
|
||||||
// Rectangle
|
// Rectangle
|
||||||
ExPolygon expoly;
|
ExPolygon expoly;
|
||||||
coord_t scaled_w = coord_t(scale_(10));
|
coord_t scaled_w = coord_t(scale_(10));
|
||||||
expoly.contour.points = { { 0, 0 }, { 0, scaled_w, }, { scaled_w, scaled_w }, { scaled_w, 0 } };
|
expoly.contour.points = { Vec2crd{ 0, 0 }, Vec2crd{ 0, scaled_w, }, Vec2crd{ scaled_w, scaled_w }, Vec2crd{ scaled_w, 0 } };
|
||||||
// Narrow part
|
// Narrow part
|
||||||
ExPolygon expoly2;
|
ExPolygon expoly2;
|
||||||
coord_t scaled_h = coord_t(scale_(0.8));
|
coord_t scaled_h = coord_t(scale_(0.8));
|
||||||
|
|
Loading…
Reference in a new issue