diff --git a/README.md b/README.md
index f6c0677c48..9d8f210d21 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,21 @@
-_Q: Oh cool, a new RepRap slicer?_
+# Slic3r Prusa Edition
-A: Yes.
-
-Slic3r
-======
Prebuilt Windows, OSX and Linux binaries are available through the [git releases page](https://github.com/prusa3d/Slic3r/releases).
-
-
-Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code instructions for
-3D printers. It's compatible with any modern printer based on the RepRap toolchain,
-including all those based on the Marlin, Sprinter and Repetier firmware. It also works
+Slic3r takes 3D models (STL, OBJ, AMF) and converts them into G-code
+instructions for FFF printers or PNG layers for mSLA 3D printers. It's
+compatible with any modern printer based on the RepRap toolchain, including all
+those based on the Marlin, Prusa, Sprinter and Repetier firmware. It also works
with Mach3, LinuxCNC and Machinekit controllers.
-See the [project homepage](http://slic3r.org/) at slic3r.org and the
-[manual](http://manual.slic3r.org/) for more information.
+See the [project homepage](https://www.prusa3d.com/slic3r-prusa-edition/) and
+the [documentation directory](doc/) for more information.
### What language is it written in?
-The core geometric algorithms and data structures are written in C++,
-and Perl is used for high-level flow abstraction, GUI and testing.
-If you're wondering why Perl, see https://xkcd.com/224/
+All user facing code is written in C++, and some legacy code as well as unit
+tests are written in Perl. Perl is not required for either development or use
+of Slic3r.
The C++ API is public and its use in other projects is encouraged.
The goal is to make Slic3r fully modular so that any part of its logic
@@ -49,34 +44,23 @@ Other major features are:
* several infill patterns including honeycomb, spirals, Hilbert curves
* support material, raft, brim, skirt
* **standby temperature** and automatic wiping for multi-extruder printing
-* customizable **G-code macros** and output filename with variable placeholders
+* [customizable **G-code macros**](https://github.com/prusa3d/Slic3r/wiki/Slic3r-Prusa-Edition-Macro-Language) and output filename with variable placeholders
* support for **post-processing scripts**
* **cooling logic** controlling fan speed and dynamic print speed
-### How to install?
+### Development
-You can download a precompiled package from [slic3r.org](http://slic3r.org/);
-it will run without the need for any dependency.
-
-If you want to compile the source yourself follow the instructions on one of these wiki pages:
-* [Linux](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-GNU-Linux)
-* [Windows](https://github.com/prusa3d/Slic3r/wiki/How-to-compile-Slic3r-Prusa-Edition-on-MS-Windows)
-* [Mac OSX](https://github.com/alexrj/Slic3r/wiki/Running-Slic3r-from-git-on-OS-X)
+If you want to compile the source yourself, follow the instructions on one of
+these documentation pages:
+* [Linux](doc/How%20to%20build%20-%20Linux%20et%20al.md)
+* [macOS](doc/How%20to%20build%20-%20Mac%20OS.md)
+* [Windows](doc/How%20to%20build%20-%20Windows.md)
### Can I help?
Sure! You can do the following to find things that are available to help with:
-* [Pull Request Milestone](https://github.com/alexrj/Slic3r/milestone/31)
- * Please comment in the related github issue that you are working on it so that other people know.
-* Items in the [TODO](https://github.com/alexrj/Slic3r/wiki/TODO) wiki page.
- * Please comment in the related github issue that you are working on it so that other people know.
-* Drop me a line at aar@cpan.org.
-* You can also find me (rarely) in #reprap and in #slic3r on [FreeNode](https://webchat.freenode.net) with the nickname _Sound_. Another contributor, _LoH_, is also in both channels.
-* Add an [issue](https://github.com/alexrj/Slic3r/issues) to the github tracker if it isn't already present.
-
-Before sending patches and pull requests contact me (preferably through opening a github issue or commenting on an existing, related, issue) to discuss your proposed
-changes: this way we'll ensure nobody wastes their time and no conflicts arise
-in development.
+* Add an [issue](https://github.com/prusa3d/Slic3r/issues) to the github tracker if it isn't already present.
+* Look at [issues labeled "volunteer needed"](https://github.com/prusa3d/Slic3r/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3A%22volunteer+needed%22)
### What's Slic3r license?
diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake
index a7397316f4..0806c23887 100644
--- a/deps/deps-windows.cmake
+++ b/deps/deps-windows.cmake
@@ -62,7 +62,7 @@ ExternalProject_Add(dep_tbb
-DTBB_BUILD_SHARED=OFF
-DTBB_BUILD_TESTS=OFF
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
- BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj
+ BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
if (${DEP_DEBUG})
@@ -70,7 +70,7 @@ if (${DEP_DEBUG})
ExternalProject_Add_Step(dep_tbb build_debug
DEPENDEES build
DEPENDERS install
- COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj
+ COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()
@@ -86,7 +86,7 @@ ExternalProject_Add(dep_gtest
-Dgtest_force_shared_crt=ON
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
- BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj
+ BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
if (${DEP_DEBUG})
@@ -94,7 +94,7 @@ if (${DEP_DEBUG})
ExternalProject_Add_Step(dep_gtest build_debug
DEPENDEES build
DEPENDERS install
- COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj
+ COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()
@@ -114,7 +114,7 @@ ExternalProject_Add(dep_nlopt
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=d
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
- BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj
+ BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
if (${DEP_DEBUG})
@@ -122,7 +122,7 @@ if (${DEP_DEBUG})
ExternalProject_Add_Step(dep_nlopt build_debug
DEPENDEES build
DEPENDERS install
- COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj
+ COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()
@@ -138,7 +138,7 @@ ExternalProject_Add(dep_zlib
"-DINSTALL_BIN_DIR=${CMAKE_CURRENT_BINARY_DIR}\\fallout" # I found no better way of preventing zlib from creating & installing DLLs :-/
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
- BUILD_COMMAND msbuild /P:Configuration=Release INSTALL.vcxproj
+ BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
if (${DEP_DEBUG})
@@ -146,7 +146,7 @@ if (${DEP_DEBUG})
ExternalProject_Add_Step(dep_zlib build_debug
DEPENDEES build
DEPENDERS install
- COMMAND msbuild /P:Configuration=Debug INSTALL.vcxproj
+ COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()
diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md
index 5de983dd77..331a3533a1 100644
--- a/doc/How to build - Windows.md
+++ b/doc/How to build - Windows.md
@@ -12,7 +12,7 @@ _Note:_ Thanks to [**@supermerill**](https://github.com/supermerill) for testing
### Dependencies
On Windows Slic3r is built against statically built libraries.
-We provide a prebuilt package of all the needed dependencies.
+We provide a prebuilt package of all the needed dependencies. This package only works on Visual Studio 2013, so if you are using a newer version of Visual Studio, you need to compile the dependencies yourself as per [below](#building-the-dependencies-package-yourself).
The package comes in a several variants:
- [64 bit, Release mode only](https://bintray.com/vojtechkral/Slic3r-PE/download_file?file_path=destdir-64.7z) (41 MB, 578 MB unpacked)
@@ -28,7 +28,7 @@ Alternatively you can also compile the dependencies yourself, see below.
### Building Slic3r PE with Visual Studio
-First obtain the Slic3 PE sources via either git or by extracting the source archive.
+First obtain the Slic3r PE sources via either git or by extracting the source archive.
Then you will need to note down the so-called 'prefix path' to the dependencies, this is the location of the dependencies packages + `\usr\local` appended.
For example on 64 bits this would be `C:\local\destdir-64\usr\local`. The prefix path will need to be passed to CMake.
@@ -66,7 +66,7 @@ There are several options for building from the command line:
To build with msbuild, use the same CMake command as in previous paragraph and then build using
- msbuild /P:Configuration=Release ALL_BUILD.vcxproj
+ msbuild /m /P:Configuration=Release ALL_BUILD.vcxproj
To build with Ninja or nmake, replace the `-G` option in the CMake call with `-G Ninja` or `-G "NMake Makefiles"` , respectively.
Then use either `ninja` or `nmake` to start the build.
@@ -84,7 +84,7 @@ Then `cd` into the `deps` directory and use these commands to build:
mkdir build
cd build
cmake .. -G "Visual Studio 12 Win64" -DDESTDIR="C:\local\destdir-custom"
- msbuild ALL_BUILD.vcxproj
+ msbuild /m ALL_BUILD.vcxproj
You can also use the Visual Studio GUI or other generators as mentioned above.
@@ -97,7 +97,11 @@ place the `build` directory relatively close to the drive root.
Note that the build variant that you may choose using Visual Studio (i.e. _Release_ or _Debug_ etc.) when building the dependency package is **not relevant**.
The dependency build will by default build _both_ the _Release_ and _Debug_ variants regardless of what you choose in Visual Studio.
-You can disable building of the debug variant by passing the `-DDEP_DEBUG=OFF` option to CMake, this will only produce a _Release_ build.
+You can disable building of the debug variant by passing the
+
+ -DDEP_DEBUG=OFF
+
+option to CMake, this will only produce a _Release_ build.
Refer to the CMake scripts inside the `deps` directory to see which dependencies are built in what versions and how this is done.
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index ef60ab3fa9..9d25318136 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -30,6 +30,9 @@ set(SLIC3R_GUI_SOURCES
GUI/GLCanvas3DManager.cpp
GUI/Selection.hpp
GUI/Selection.cpp
+ GUI/Gizmos/GLGizmos.hpp
+ GUI/Gizmos/GLGizmosManager.cpp
+ GUI/Gizmos/GLGizmosManager.hpp
GUI/Gizmos/GLGizmoBase.cpp
GUI/Gizmos/GLGizmoBase.hpp
GUI/Gizmos/GLGizmoMove.cpp
diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp
index 2367938147..05f4fd8fdb 100644
--- a/src/slic3r/GUI/3DBed.cpp
+++ b/src/slic3r/GUI/3DBed.cpp
@@ -495,11 +495,11 @@ void Bed3D::render_prusa(const std::string &key, bool bottom) const
// use anisotropic filter if graphic card allows
GLfloat max_anisotropy = 0.0f;
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
- ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
+ glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy));
// use higher resolution images if graphic card allows
GLint max_tex_size;
- ::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
+ glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size));
// clamp or the texture generation becomes too slow
max_tex_size = std::min(max_tex_size, 8192);
@@ -621,7 +621,6 @@ void Bed3D::render_prusa_shader(bool transparent) const
m_shader.stop_using();
}
}
-
#else
void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) const
{
@@ -629,7 +628,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons
// use higher resolution images if graphic card allows
GLint max_tex_size;
- ::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
+ glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size));
// temporary set to lowest resolution
max_tex_size = 2048;
@@ -644,7 +643,7 @@ void Bed3D::render_prusa(const std::string &key, float theta, bool useVBOs) cons
// use anisotropic filter if graphic card allows
GLfloat max_anisotropy = 0.0f;
if (glewIsSupported("GL_EXT_texture_filter_anisotropic"))
- ::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
+ glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy));
std::string filename = tex_path + "_top.png";
if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename))
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 57c227e078..9e8a18b89e 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -41,6 +41,7 @@ void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char
switch (err) {
case GL_INVALID_ENUM: sErr = "Invalid Enum"; break;
case GL_INVALID_VALUE: sErr = "Invalid Value"; break;
+ // be aware that GL_INVALID_OPERATION is generated if glGetError is executed between the execution of glBegin and the corresponding execution of glEnd
case GL_INVALID_OPERATION: sErr = "Invalid Operation"; break;
case GL_STACK_OVERFLOW: sErr = "Stack Overflow"; break;
case GL_STACK_UNDERFLOW: sErr = "Stack Underflow"; break;
@@ -98,25 +99,25 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
if (use_VBOs) {
if (! empty()) {
- glsafe(glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
- glsafe(glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW));
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
+ glsafe(::glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
+ glsafe(::glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
this->vertices_and_normals_interleaved.clear();
}
if (! this->triangle_indices.empty()) {
- glsafe(glGenBuffers(1, &this->triangle_indices_VBO_id));
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
- glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW));
+ glsafe(::glGenBuffers(1, &this->triangle_indices_VBO_id));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
+ glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW));
this->triangle_indices.clear();
}
if (! this->quad_indices.empty()) {
- glsafe(glGenBuffers(1, &this->quad_indices_VBO_id));
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
- glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW));
+ glsafe(::glGenBuffers(1, &this->quad_indices_VBO_id));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
+ glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW));
this->quad_indices.clear();
}
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
this->shrink_to_fit();
}
@@ -124,15 +125,15 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
void GLIndexedVertexArray::release_geometry()
{
if (this->vertices_and_normals_interleaved_VBO_id) {
- glsafe(glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
+ glsafe(::glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
this->vertices_and_normals_interleaved_VBO_id = 0;
}
if (this->triangle_indices_VBO_id) {
- glsafe(glDeleteBuffers(1, &this->triangle_indices_VBO_id));
+ glsafe(::glDeleteBuffers(1, &this->triangle_indices_VBO_id));
this->triangle_indices_VBO_id = 0;
}
if (this->quad_indices_VBO_id) {
- glsafe(glDeleteBuffers(1, &this->quad_indices_VBO_id));
+ glsafe(::glDeleteBuffers(1, &this->quad_indices_VBO_id));
this->quad_indices_VBO_id = 0;
}
this->clear();
@@ -142,42 +143,42 @@ void GLIndexedVertexArray::release_geometry()
void GLIndexedVertexArray::render() const
{
if (this->vertices_and_normals_interleaved_VBO_id) {
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
- glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
- glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
+ glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
+ glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
} else {
- glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
- glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
+ glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
+ glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
}
- glsafe(glEnableClientState(GL_VERTEX_ARRAY));
- glsafe(glEnableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
if (this->indexed()) {
if (this->vertices_and_normals_interleaved_VBO_id) {
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_size > 0) {
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
- glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
+ glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr));
}
if (this->quad_indices_size > 0) {
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
- glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
+ glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr));
}
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
// Render in an immediate mode.
if (! this->triangle_indices.empty())
- glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data()));
+ glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data()));
if (! this->quad_indices.empty())
- glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data()));
+ glsafe(::glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data()));
}
} else
- glsafe(glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6)));
+ glsafe(::glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6)));
if (this->vertices_and_normals_interleaved_VBO_id)
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
- glsafe(glDisableClientState(GL_VERTEX_ARRAY));
- glsafe(glDisableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
}
void GLIndexedVertexArray::render(
@@ -190,35 +191,35 @@ void GLIndexedVertexArray::render(
if (this->vertices_and_normals_interleaved_VBO_id) {
// Render using the Vertex Buffer Objects.
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
- glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
- glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
- glsafe(glEnableClientState(GL_VERTEX_ARRAY));
- glsafe(glEnableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
+ glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
+ glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
if (this->triangle_indices_size > 0) {
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
- glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
+ glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
}
if (this->quad_indices_size > 0) {
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
- glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
+ glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
}
- glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
- glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
// Render in an immediate mode.
- glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
- glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
- glsafe(glEnableClientState(GL_VERTEX_ARRAY));
- glsafe(glEnableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
+ glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
if (! this->triangle_indices.empty())
- glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first)));
+ glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first)));
if (! this->quad_indices.empty())
- glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first)));
+ glsafe(::glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first)));
}
- glsafe(glDisableClientState(GL_VERTEX_ARRAY));
- glsafe(glDisableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
}
const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
@@ -736,7 +737,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
typedef std::pair GLVolumeWithZ;
typedef std::vector GLVolumesWithZList;
-static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, std::function filter_func)
+static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function filter_func)
{
GLVolumesWithZList list;
list.reserve(volumes.size());
@@ -753,12 +754,9 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
{
- Transform3d modelview_matrix;
- glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()));
-
for (GLVolumeWithZ& volume : list)
{
- volume.second = volume.first->bounding_box.transformed(modelview_matrix * volume.first->world_matrix()).max(2);
+ volume.second = volume.first->bounding_box.transformed(view_matrix * volume.first->world_matrix()).max(2);
}
std::sort(list.begin(), list.end(),
@@ -769,7 +767,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
return list;
}
-void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function filter_func) const
+void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const
{
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
@@ -783,13 +781,14 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
GLint current_program_id;
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
- 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 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_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_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -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 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_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_worldmatrix_id = (current_program_id > 0) ? ::glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
+ glcheck();
if (print_box_min_id != -1)
glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min));
@@ -803,7 +802,8 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
if (clipping_plane_id != -1)
glsafe(::glUniform4fv(clipping_plane_id, 1, (const GLfloat*)clipping_plane));
- GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
+ GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
+
for (GLVolumeWithZ& volume : to_render) {
volume.first->set_render_color();
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
@@ -821,32 +821,32 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
glsafe(::glDisable(GL_BLEND));
}
-void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, std::function filter_func) const
+void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const
{
- glsafe(glEnable(GL_BLEND));
- glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
+ glsafe(::glEnable(GL_BLEND));
+ glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
- glsafe(glCullFace(GL_BACK));
+ glsafe(::glCullFace(GL_BACK));
if (disable_cullface)
glsafe(::glDisable(GL_CULL_FACE));
- glsafe(glEnableClientState(GL_VERTEX_ARRAY));
- glsafe(glEnableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
- GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
+ GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, view_matrix, filter_func);
for (GLVolumeWithZ& volume : to_render)
{
volume.first->set_render_color();
volume.first->render_legacy();
}
- glsafe(glDisableClientState(GL_VERTEX_ARRAY));
- glsafe(glDisableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (disable_cullface)
glsafe(::glEnable(GL_CULL_FACE));
- glsafe(glDisable(GL_BLEND));
+ glsafe(::glDisable(GL_BLEND));
}
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state)
@@ -1775,7 +1775,8 @@ void GLModel::render_VBOs() const
GLint current_program_id;
glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
- 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();
m_volume.render_VBOs(color_id, -1, -1);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index 0ed8d2e6b1..1bb4149748 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -19,9 +19,11 @@
extern void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char *function_name);
inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); }
#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false)
+#define glcheck() do { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); } while (false)
#else
inline void glAssertRecentCall() { }
#define glsafe(cmd) cmd
+#define glcheck()
#endif
namespace Slic3r {
@@ -466,8 +468,8 @@ public:
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
// Render the volumes by OpenGL.
- void render_VBOs(ERenderType type, bool disable_cullface, std::function filter_func = std::function()) const;
- void render_legacy(ERenderType type, bool disable_cullface, std::function filter_func = std::function()) const;
+ void render_VBOs(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const;
+ void render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const;
// Finalize the initialization of the geometry & indices,
// upload the geometry and indices to OpenGL VBO objects
diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp
index c748efa64d..7a1023e621 100644
--- a/src/slic3r/GUI/Camera.cpp
+++ b/src/slic3r/GUI/Camera.cpp
@@ -1,9 +1,21 @@
#include "libslic3r/libslic3r.h"
#include "Camera.hpp"
+#include "3DScene.hpp"
+
+#include
static const float GIMBALL_LOCK_THETA_MAX = 180.0f;
+// phi / theta angles to orient the camera.
+static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f };
+static const float VIEW_LEFT[2] = { 90.0f, 90.0f };
+static const float VIEW_RIGHT[2] = { -90.0f, 90.0f };
+static const float VIEW_TOP[2] = { 0.0f, 0.0f };
+static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f };
+static const float VIEW_FRONT[2] = { 0.0f, 90.0f };
+static const float VIEW_REAR[2] = { 180.0f, 90.0f };
+
namespace Slic3r {
namespace GUI {
@@ -57,6 +69,64 @@ void Camera::set_scene_box(const BoundingBoxf3& box)
m_scene_box = box;
}
+bool Camera::select_view(const std::string& direction)
+{
+ const float* dir_vec = nullptr;
+
+ if (direction == "iso")
+ dir_vec = VIEW_DEFAULT;
+ else if (direction == "left")
+ dir_vec = VIEW_LEFT;
+ else if (direction == "right")
+ dir_vec = VIEW_RIGHT;
+ else if (direction == "top")
+ dir_vec = VIEW_TOP;
+ else if (direction == "bottom")
+ dir_vec = VIEW_BOTTOM;
+ else if (direction == "front")
+ dir_vec = VIEW_FRONT;
+ else if (direction == "rear")
+ dir_vec = VIEW_REAR;
+
+ if (dir_vec != nullptr)
+ {
+ phi = dir_vec[0];
+ set_theta(dir_vec[1], false);
+ return true;
+ }
+ else
+ return false;
+}
+
+void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h) const
+{
+ glsafe(::glViewport(0, 0, w, h));
+ glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
+}
+
+void Camera::apply_view_matrix() const
+{
+ glsafe(::glMatrixMode(GL_MODELVIEW));
+ glsafe(::glLoadIdentity());
+
+ glsafe(::glRotatef(-m_theta, 1.0f, 0.0f, 0.0f)); // pitch
+ glsafe(::glRotatef(phi, 0.0f, 0.0f, 1.0f)); // yaw
+ glsafe(::glTranslated(-m_target(0), -m_target(1), -m_target(2)));
+
+ glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, m_view_matrix.data()));
+}
+
+void Camera::apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const
+{
+ glsafe(::glMatrixMode(GL_PROJECTION));
+ glsafe(::glLoadIdentity());
+
+ glsafe(::glOrtho(x_min, x_max, y_min, y_max, z_min, z_max));
+ glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
+
+ glsafe(::glMatrixMode(GL_MODELVIEW));
+}
+
} // GUI
} // Slic3r
diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp
index d50dc6e4d9..d19bc870ef 100644
--- a/src/slic3r/GUI/Camera.hpp
+++ b/src/slic3r/GUI/Camera.hpp
@@ -2,6 +2,7 @@
#define slic3r_Camera_hpp_
#include "libslic3r/BoundingBox.hpp"
+#include
namespace Slic3r {
namespace GUI {
@@ -26,6 +27,10 @@ private:
Vec3d m_target;
float m_theta;
+ mutable std::array m_viewport;
+ mutable Transform3d m_view_matrix;
+ mutable Transform3d m_projection_matrix;
+
BoundingBoxf3 m_scene_box;
public:
@@ -41,6 +46,22 @@ public:
const BoundingBoxf3& get_scene_box() const { return m_scene_box; }
void set_scene_box(const BoundingBoxf3& box);
+
+ bool select_view(const std::string& direction);
+
+ const std::array& get_viewport() const { return m_viewport; }
+ const Transform3d& get_view_matrix() const { return m_view_matrix; }
+ const Transform3d& get_projection_matrix() const { return m_projection_matrix; }
+
+ Vec3d get_dir_right() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(0); }
+ Vec3d get_dir_up() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(1); }
+ Vec3d get_dir_forward() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(2); }
+
+ Vec3d get_position() const { return m_view_matrix.matrix().block(0, 0, 3, 3).row(3); }
+
+ void apply_viewport(int x, int y, unsigned int w, unsigned int h) const;
+ void apply_view_matrix() const;
+ void apply_ortho_projection(float x_min, float x_max, float y_min, float y_max, float z_min, float z_max) const;
};
} // GUI
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 717ebcddaf..cee3bcf0eb 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -56,15 +56,6 @@
static const float TRACKBALLSIZE = 0.8f;
static const float GROUND_Z = -0.02f;
-// phi / theta angles to orient the camera.
-static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f };
-static const float VIEW_LEFT[2] = { 90.0f, 90.0f };
-static const float VIEW_RIGHT[2] = { -90.0f, 90.0f };
-static const float VIEW_TOP[2] = { 0.0f, 0.0f };
-static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f };
-static const float VIEW_FRONT[2] = { 0.0f, 90.0f };
-static const float VIEW_REAR[2] = { 180.0f, 90.0f };
-
static const float GIZMO_RESET_BUTTON_HEIGHT = 22.0f;
static const float GIZMO_RESET_BUTTON_WIDTH = 70.f;
@@ -125,62 +116,6 @@ void Size::set_scale_factor(int scale_factor)
m_scale_factor = scale_factor;
}
-Rect::Rect()
- : m_left(0.0f)
- , m_top(0.0f)
- , m_right(0.0f)
- , m_bottom(0.0f)
-{
-}
-
-Rect::Rect(float left, float top, float right, float bottom)
- : m_left(left)
- , m_top(top)
- , m_right(right)
- , m_bottom(bottom)
-{
-}
-
-float Rect::get_left() const
-{
- return m_left;
-}
-
-void Rect::set_left(float left)
-{
- m_left = left;
-}
-
-float Rect::get_top() const
-{
- return m_top;
-}
-
-void Rect::set_top(float top)
-{
- m_top = top;
-}
-
-float Rect::get_right() const
-{
- return m_right;
-}
-
-void Rect::set_right(float right)
-{
- m_right = right;
-}
-
-float Rect::get_bottom() const
-{
- return m_bottom;
-}
-
-void Rect::set_bottom(float bottom)
-{
- m_bottom = bottom;
-}
-
#if !ENABLE_TEXTURES_FROM_SVG
GLCanvas3D::Shader::Shader()
: m_shader(nullptr)
@@ -283,7 +218,7 @@ GLCanvas3D::LayersEditing::~LayersEditing()
{
if (m_z_texture_id != 0)
{
- ::glDeleteTextures(1, &m_z_texture_id);
+ glsafe(::glDeleteTextures(1, &m_z_texture_id));
m_z_texture_id = 0;
}
delete m_slicing_parameters;
@@ -297,14 +232,14 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename,
if (!m_shader.init(vertex_shader_filename, fragment_shader_filename))
return false;
- ::glGenTextures(1, (GLuint*)&m_z_texture_id);
- ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
@@ -360,12 +295,12 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
const Rect& bar_rect = get_bar_rect_viewport(canvas);
const Rect& reset_rect = get_reset_rect_viewport(canvas);
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
// The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth),
// where x, y is the window size divided by $self->_zoom.
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
_render_tooltip_texture(canvas, bar_rect, reset_rect);
_render_reset_texture(reset_rect);
@@ -373,9 +308,9 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
_render_profile(bar_rect);
// Revert the matrices.
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_DEPTH_TEST));
}
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
@@ -430,7 +365,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height();
- float zoom = canvas.get_camera_zoom();
+ float zoom = canvas.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom);
@@ -442,7 +377,7 @@ Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas
float half_w = 0.5f * (float)cnv_size.get_width();
float half_h = 0.5f * (float)cnv_size.get_height();
- float zoom = canvas.get_camera_zoom();
+ float zoom = canvas.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
return Rect((half_w - thickness_bar_width(canvas)) * inv_zoom, (-half_h + reset_button_height(canvas)) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
@@ -473,7 +408,7 @@ void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas
const float width = (float)m_tooltip_texture.get_width() * scale;
const float height = (float)m_tooltip_texture.get_height() * scale;
- float zoom = canvas.get_camera_zoom();
+ float zoom = canvas.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float gap = 10.0f * inv_zoom;
@@ -511,8 +446,8 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas
// The shader requires the original model coordinates when rendering to the texture, so we pass it the unit matrix
m_shader.set_uniform("volume_world_matrix", UNIT_MATRIX);
- ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
+ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
// Render the color bar
float l = bar_rect.get_left();
@@ -526,8 +461,8 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas
::glVertex3f(r, b, 0.0f);
::glVertex3f(r, t, m_object_max_z);
::glVertex3f(l, t, m_object_max_z);
- ::glEnd();
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ glsafe(::glEnd());
+ glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
m_shader.stop_using();
}
@@ -543,18 +478,18 @@ void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const
float x = bar_rect.get_left() + (float)m_slicing_parameters->layer_height * scale_x;
// Baseline
- ::glColor3f(0.0f, 0.0f, 0.0f);
+ glsafe(::glColor3f(0.0f, 0.0f, 0.0f));
::glBegin(GL_LINE_STRIP);
::glVertex2f(x, bar_rect.get_bottom());
::glVertex2f(x, bar_rect.get_top());
- ::glEnd();
+ glsafe(::glEnd());
// Curve
- ::glColor3f(0.0f, 0.0f, 1.0f);
+ glsafe(::glColor3f(0.0f, 0.0f, 1.0f));
::glBegin(GL_LINE_STRIP);
for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2)
::glVertex2f(bar_rect.get_left() + (float)m_layer_height_profile[i + 1] * scale_x, bar_rect.get_bottom() + (float)m_layer_height_profile[i] * scale_y);
- ::glEnd();
+ glsafe(::glEnd());
}
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection &volumes) const
@@ -565,51 +500,52 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
assert(shader_id > 0);
GLint current_program_id;
- glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id);
+ glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
if (shader_id > 0 && shader_id != current_program_id)
// The layer editing shader is not yet active. Activate it.
- glUseProgram(shader_id);
+ glsafe(::glUseProgram(shader_id));
else
// The layer editing shader was already active.
current_program_id = -1;
- GLint z_to_texture_row_id = glGetUniformLocation(shader_id, "z_to_texture_row");
- GLint z_texture_row_to_normalized_id = glGetUniformLocation(shader_id, "z_texture_row_to_normalized");
- GLint z_cursor_id = glGetUniformLocation(shader_id, "z_cursor");
- GLint z_cursor_band_width_id = glGetUniformLocation(shader_id, "z_cursor_band_width");
- GLint world_matrix_id = glGetUniformLocation(shader_id, "volume_world_matrix");
+ GLint z_to_texture_row_id = ::glGetUniformLocation(shader_id, "z_to_texture_row");
+ GLint z_texture_row_to_normalized_id = ::glGetUniformLocation(shader_id, "z_texture_row_to_normalized");
+ GLint z_cursor_id = ::glGetUniformLocation(shader_id, "z_cursor");
+ GLint z_cursor_band_width_id = ::glGetUniformLocation(shader_id, "z_cursor_band_width");
+ GLint world_matrix_id = ::glGetUniformLocation(shader_id, "volume_world_matrix");
+ glcheck();
if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1)
{
const_cast(this)->generate_layer_height_texture();
// Uniforms were resolved, go ahead using the layer editing shader.
- glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z)));
- glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height));
- glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)));
- glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width));
+ glsafe(::glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z))));
+ glsafe(::glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height)));
+ glsafe(::glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas))));
+ glsafe(::glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width)));
// Initialize the layer height texture mapping.
GLsizei w = (GLsizei)m_layers_texture.width;
GLsizei h = (GLsizei)m_layers_texture.height;
GLsizei half_w = w / 2;
GLsizei half_h = h / 2;
- ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data());
- glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4);
+ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
+ glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data()));
+ glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4));
for (const GLVolume *glvolume : volumes.volumes) {
// Render the object using the layer editing shader and texture.
if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier)
continue;
- ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data());
+ glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data()));
glvolume->render();
}
// Revert back to the previous shader.
glBindTexture(GL_TEXTURE_2D, 0);
if (current_program_id > 0)
- glUseProgram(current_program_id);
+ glsafe(::glUseProgram(current_program_id));
}
else
{
@@ -619,7 +555,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
// Render the object using the layer editing shader and texture.
if (!glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier)
continue;
- ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data());
+ glsafe(::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast().data()));
glvolume->render();
}
}
@@ -731,901 +667,9 @@ GLCanvas3D::Mouse::Mouse()
: dragging(false)
, position(DBL_MAX, DBL_MAX)
, scene_position(DBL_MAX, DBL_MAX, DBL_MAX)
- , ignore_up_event(false)
{
}
-#if ENABLE_SVG_ICONS
-const float GLCanvas3D::Gizmos::Default_Icons_Size = 64;
-#endif // ENABLE_SVG_ICONS
-
-GLCanvas3D::Gizmos::Gizmos()
- : m_enabled(false)
-#if ENABLE_SVG_ICONS
- , m_icons_texture_dirty(true)
-#endif // ENABLE_SVG_ICONS
- , m_current(Undefined)
-#if ENABLE_SVG_ICONS
- , m_overlay_icons_size(Default_Icons_Size)
- , m_overlay_scale(1.0f)
- , m_overlay_border(5.0f)
- , m_overlay_gap_y(5.0f)
-{
-}
-#else
-{
- set_overlay_scale(1.0);
-}
-#endif // ENABLE_SVG_ICONS
-
-GLCanvas3D::Gizmos::~Gizmos()
-{
- reset();
-}
-
-bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
-{
-#if !ENABLE_SVG_ICONS
- m_icons_texture.metadata.filename = "gizmos.png";
- m_icons_texture.metadata.icon_size = 64;
-
- if (!m_icons_texture.metadata.filename.empty())
- {
- if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false))
- {
- reset();
- return false;
- }
- }
-#endif // !ENABLE_SVG_ICONS
-
- m_background_texture.metadata.filename = "toolbar_background.png";
- m_background_texture.metadata.left = 16;
- m_background_texture.metadata.top = 16;
- m_background_texture.metadata.right = 16;
- m_background_texture.metadata.bottom = 16;
-
- if (!m_background_texture.metadata.filename.empty())
- {
- if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false))
- {
- reset();
- return false;
- }
- }
-
-#if ENABLE_SVG_ICONS
- GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0);
-#else
- GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- return false;
-
- if (!gizmo->init())
- return false;
-
- m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
-
-#if ENABLE_SVG_ICONS
- gizmo = new GLGizmoScale3D(parent, "scale.svg", 1);
-#else
- gizmo = new GLGizmoScale3D(parent, 1);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- return false;
-
- if (!gizmo->init())
- return false;
-
- m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
-
-#if ENABLE_SVG_ICONS
- gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2);
-#else
- gizmo = new GLGizmoRotate3D(parent, 2);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- {
- reset();
- return false;
- }
-
- if (!gizmo->init())
- {
- reset();
- return false;
- }
-
- m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
-
-#if ENABLE_SVG_ICONS
- gizmo = new GLGizmoFlatten(parent, "place.svg", 3);
-#else
- gizmo = new GLGizmoFlatten(parent, 3);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- return false;
-
- if (!gizmo->init()) {
- reset();
- return false;
- }
-
- m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo));
-
-#if ENABLE_SVG_ICONS
- gizmo = new GLGizmoCut(parent, "cut.svg", 4);
-#else
- gizmo = new GLGizmoCut(parent, 4);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- return false;
-
- if (!gizmo->init()) {
- reset();
- return false;
- }
-
- m_gizmos.insert(GizmosMap::value_type(Cut, gizmo));
-
-#if ENABLE_SVG_ICONS
- gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5);
-#else
- gizmo = new GLGizmoSlaSupports(parent, 5);
-#endif // ENABLE_SVG_ICONS
- if (gizmo == nullptr)
- return false;
-
- if (!gizmo->init()) {
- reset();
- return false;
- }
-
- m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo));
-
- return true;
-}
-
-bool GLCanvas3D::Gizmos::is_enabled() const
-{
- return m_enabled;
-}
-
-void GLCanvas3D::Gizmos::set_enabled(bool enable)
-{
- m_enabled = enable;
-}
-
-#if ENABLE_SVG_ICONS
-void GLCanvas3D::Gizmos::set_overlay_icon_size(float size)
-{
- if (m_overlay_icons_size != size)
- {
- m_overlay_icons_size = size;
- m_icons_texture_dirty = true;
- }
-}
-#endif // ENABLE_SVG_ICONS
-
-void GLCanvas3D::Gizmos::set_overlay_scale(float scale)
-{
-#if ENABLE_SVG_ICONS
- if (m_overlay_scale != scale)
- {
- m_overlay_scale = scale;
- m_icons_texture_dirty = true;
- }
-#else
- m_overlay_icons_scale = scale;
- m_overlay_border = 5.0f * scale;
- m_overlay_gap_y = 5.0f * scale;
-#endif // ENABLE_SVG_ICONS
-}
-
-std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection)
-{
- std::string name = "";
-
- if (!m_enabled)
- return name;
-
- float cnv_h = (float)canvas.get_canvas_size().get_height();
- float height = get_total_overlay_height();
-#if ENABLE_SVG_ICONS
- float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
- float scaled_border = m_overlay_border * m_overlay_scale;
- float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
- float scaled_stride_y = scaled_icons_size + scaled_gap_y;
- float top_y = 0.5f * (cnv_h - height) + scaled_border;
-#else
- float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
- float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
-#endif // ENABLE_SVG_ICONS
-
- for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
-#if ENABLE_SVG_ICONS
- bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
-#else
- bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
-#endif // ENABLE_SVG_ICONS
- if (inside)
- name = it->second->get_name();
-
- if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On))
- it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
-
-#if ENABLE_SVG_ICONS
- top_y += scaled_stride_y;
-#else
- top_y += (scaled_icons_size + m_overlay_gap_y);
-#endif // ENABLE_SVG_ICONS
- }
-
- return name;
-}
-
-void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection)
-{
- if (!m_enabled)
- return;
-
- float cnv_h = (float)canvas.get_canvas_size().get_height();
- float height = get_total_overlay_height();
-
-#if ENABLE_SVG_ICONS
- float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
- float scaled_border = m_overlay_border * m_overlay_scale;
- float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
- float scaled_stride_y = scaled_icons_size + scaled_gap_y;
- float top_y = 0.5f * (cnv_h - height) + scaled_border;
-#else
- float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
- float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
-#endif // ENABLE_SVG_ICONS
-
- for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
-#if ENABLE_SVG_ICONS
- bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
-#else
- bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
-#endif // ENABLE_SVG_ICONS
- if (it->second->is_activable(selection) && inside)
- {
- if ((it->second->get_state() == GLGizmoBase::On))
- {
- it->second->set_state(GLGizmoBase::Hover);
- m_current = Undefined;
- }
- else if ((it->second->get_state() == GLGizmoBase::Hover))
- {
- it->second->set_state(GLGizmoBase::On);
- m_current = it->first;
- }
- }
- else
- it->second->set_state(GLGizmoBase::Off);
-
-#if ENABLE_SVG_ICONS
- top_y += scaled_stride_y;
-#else
- top_y += (scaled_icons_size + m_overlay_gap_y);
-#endif // ENABLE_SVG_ICONS
- }
-
- GizmosMap::iterator it = m_gizmos.find(m_current);
- if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On))
- it->second->set_state(GLGizmoBase::On);
-}
-
-void GLCanvas3D::Gizmos::update_on_off_state(const Selection& selection)
-{
- GizmosMap::iterator it = m_gizmos.find(m_current);
- if ((it != m_gizmos.end()) && (it->second != nullptr))
- {
- if (!it->second->is_activable(selection))
- {
- it->second->set_state(GLGizmoBase::Off);
- m_current = Undefined;
- }
- }
-}
-
-void GLCanvas3D::Gizmos::reset_all_states()
-{
- if (!m_enabled)
- return;
-
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if (it->second != nullptr)
- {
- it->second->set_state(GLGizmoBase::Off);
- it->second->set_hover_id(-1);
- }
- }
-
- m_current = Undefined;
-}
-
-void GLCanvas3D::Gizmos::set_hover_id(int id)
-{
- if (!m_enabled)
- return;
-
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On))
- it->second->set_hover_id(id);
- }
-}
-
-void GLCanvas3D::Gizmos::enable_grabber(EType type, unsigned int id, bool enable)
-{
- if (!m_enabled)
- return;
-
- GizmosMap::const_iterator it = m_gizmos.find(type);
- if (it != m_gizmos.end())
- {
- if (enable)
- it->second->enable_grabber(id);
- else
- it->second->disable_grabber(id);
- }
-}
-
-bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const
-{
- if (!m_enabled)
- return false;
-
- float cnv_h = (float)canvas.get_canvas_size().get_height();
- float height = get_total_overlay_height();
-
-#if ENABLE_SVG_ICONS
- float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
- float scaled_border = m_overlay_border * m_overlay_scale;
- float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
- float scaled_stride_y = scaled_icons_size + scaled_gap_y;
- float top_y = 0.5f * (cnv_h - height) + scaled_border;
-#else
- float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
- float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
-#endif // ENABLE_SVG_ICONS
-
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
-#if ENABLE_SVG_ICONS
- if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
-#else
- if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
-#endif // ENABLE_SVG_ICONS
- return true;
-
-#if ENABLE_SVG_ICONS
- top_y += scaled_stride_y;
-#else
- top_y += (scaled_icons_size + m_overlay_gap_y);
-#endif // ENABLE_SVG_ICONS
- }
-
- return false;
-}
-
-bool GLCanvas3D::Gizmos::grabber_contains_mouse() const
-{
- if (!m_enabled)
- return false;
-
- GLGizmoBase* curr = get_current();
- return (curr != nullptr) ? (curr->get_hover_id() != -1) : false;
-}
-
-void GLCanvas3D::Gizmos::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos)
-{
- if (!m_enabled)
- return;
-
- GLGizmoBase* curr = get_current();
- if (curr != nullptr)
- curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection);
-}
-
-GLCanvas3D::Gizmos::EType GLCanvas3D::Gizmos::get_current_type() const
-{
- return m_current;
-}
-
-bool GLCanvas3D::Gizmos::is_running() const
-{
- if (!m_enabled)
- return false;
-
- GLGizmoBase* curr = get_current();
- return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false;
-}
-
-bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection)
-{
- if (!m_enabled || selection.is_empty())
- return false;
-
- EType old_current = m_current;
- bool handled = false;
- for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
- int it_key = it->second->get_shortcut_key();
-
- if (it->second->is_activable(selection) && ((it_key == key - 64) || (it_key == key - 96)))
- {
- if ((it->second->get_state() == GLGizmoBase::On))
- {
- it->second->set_state(GLGizmoBase::Off);
- m_current = Undefined;
- handled = true;
- }
- else if ((it->second->get_state() == GLGizmoBase::Off))
- {
- it->second->set_state(GLGizmoBase::On);
- m_current = it->first;
- handled = true;
- }
- }
- }
-
- if (handled && (old_current != Undefined) && (old_current != m_current))
- {
- GizmosMap::const_iterator it = m_gizmos.find(old_current);
- if (it != m_gizmos.end())
- it->second->set_state(GLGizmoBase::Off);
- }
-
- return handled;
-}
-
-bool GLCanvas3D::Gizmos::is_dragging() const
-{
- if (!m_enabled)
- return false;
-
- GLGizmoBase* curr = get_current();
- return (curr != nullptr) ? curr->is_dragging() : false;
-}
-
-void GLCanvas3D::Gizmos::start_dragging(const Selection& selection)
-{
- if (!m_enabled)
- return;
-
- GLGizmoBase* curr = get_current();
- if (curr != nullptr)
- curr->start_dragging(selection);
-}
-
-void GLCanvas3D::Gizmos::stop_dragging()
-{
- if (!m_enabled)
- return;
-
- GLGizmoBase* curr = get_current();
- if (curr != nullptr)
- curr->stop_dragging();
-}
-
-Vec3d GLCanvas3D::Gizmos::get_displacement() const
-{
- if (!m_enabled)
- return Vec3d::Zero();
-
- GizmosMap::const_iterator it = m_gizmos.find(Move);
- return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_displacement() : Vec3d::Zero();
-}
-
-Vec3d GLCanvas3D::Gizmos::get_scale() const
-{
- if (!m_enabled)
- return Vec3d::Ones();
-
- GizmosMap::const_iterator it = m_gizmos.find(Scale);
- return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : Vec3d::Ones();
-}
-
-void GLCanvas3D::Gizmos::set_scale(const Vec3d& scale)
-{
- if (!m_enabled)
- return;
-
- GizmosMap::const_iterator it = m_gizmos.find(Scale);
- if (it != m_gizmos.end())
- reinterpret_cast(it->second)->set_scale(scale);
-}
-
-Vec3d GLCanvas3D::Gizmos::get_rotation() const
-{
- if (!m_enabled)
- return Vec3d::Zero();
-
- GizmosMap::const_iterator it = m_gizmos.find(Rotate);
- return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_rotation() : Vec3d::Zero();
-}
-
-void GLCanvas3D::Gizmos::set_rotation(const Vec3d& rotation)
-{
- if (!m_enabled)
- return;
-
- GizmosMap::const_iterator it = m_gizmos.find(Rotate);
- if (it != m_gizmos.end())
- reinterpret_cast(it->second)->set_rotation(rotation);
-}
-
-Vec3d GLCanvas3D::Gizmos::get_flattening_normal() const
-{
- if (!m_enabled)
- return Vec3d::Zero();
-
- GizmosMap::const_iterator it = m_gizmos.find(Flatten);
- return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_flattening_normal() : Vec3d::Zero();
-}
-
-void GLCanvas3D::Gizmos::set_flattening_data(const ModelObject* model_object)
-{
- if (!m_enabled)
- return;
-
- GizmosMap::const_iterator it = m_gizmos.find(Flatten);
- if (it != m_gizmos.end())
- reinterpret_cast(it->second)->set_flattening_data(model_object);
-}
-
-void GLCanvas3D::Gizmos::set_sla_support_data(ModelObject* model_object, const Selection& selection)
-{
- if (!m_enabled)
- return;
-
- GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
- if (it != m_gizmos.end())
- reinterpret_cast(it->second)->set_sla_support_data(model_object, selection);
-}
-
-
-// Returns true if the gizmo used the event to do something, false otherwise.
-bool GLCanvas3D::Gizmos::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down)
-{
- if (!m_enabled)
- return false;
-
- GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
- if (it != m_gizmos.end())
- return reinterpret_cast(it->second)->gizmo_event(action, mouse_position, shift_down);
-
- return false;
-}
-
-
-
-GLCanvas3D::ClippingPlane GLCanvas3D::Gizmos::get_sla_clipping_plane() const
-{
- if (!m_enabled || m_current != SlaSupports)
- return ClippingPlane::ClipsNothing();
-
- GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
- if (it != m_gizmos.end())
- return reinterpret_cast(it->second)->get_sla_clipping_plane();
-
- return ClippingPlane::ClipsNothing();
-}
-
-
-
-void GLCanvas3D::Gizmos::render_current_gizmo(const Selection& selection) const
-{
- if (!m_enabled)
- return;
-
- do_render_current_gizmo(selection);
-}
-
-void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const Selection& selection) const
-{
- if (!m_enabled)
- return;
-
- GLGizmoBase* curr = get_current();
- if (curr != nullptr)
- curr->render_for_picking(selection);
-}
-
-void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas, const Selection& selection) const
-{
- if (!m_enabled)
- return;
-
-#if ENABLE_SVG_ICONS
- if (m_icons_texture_dirty)
- generate_icons_texture();
-#endif // ENABLE_SVG_ICONS
-
- ::glDisable(GL_DEPTH_TEST);
-
- ::glPushMatrix();
- ::glLoadIdentity();
-
- do_render_overlay(canvas, selection);
-
- ::glPopMatrix();
-}
-
-
-void GLCanvas3D::Gizmos::reset()
-{
- for (GizmosMap::value_type& gizmo : m_gizmos)
- {
- delete gizmo.second;
- gizmo.second = nullptr;
- }
-
- m_gizmos.clear();
-}
-
-void GLCanvas3D::Gizmos::do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const
-{
- if (m_gizmos.empty())
- return;
-
- float cnv_w = (float)canvas.get_canvas_size().get_width();
- float cnv_h = (float)canvas.get_canvas_size().get_height();
- float zoom = canvas.get_camera_zoom();
- float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
-
- float height = get_total_overlay_height();
- float width = get_total_overlay_width();
-#if ENABLE_SVG_ICONS
- float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom;
-#else
- float scaled_border = m_overlay_border * inv_zoom;
-#endif // ENABLE_SVG_ICONS
-
- float top_x = (-0.5f * cnv_w) * inv_zoom;
- float top_y = (0.5f * height) * inv_zoom;
-
- float left = top_x;
- float top = top_y;
- float right = left + width * inv_zoom;
- float bottom = top - height * inv_zoom;
-
- // renders background
- unsigned int bg_tex_id = m_background_texture.texture.get_id();
- float bg_tex_width = (float)m_background_texture.texture.get_width();
- float bg_tex_height = (float)m_background_texture.texture.get_height();
- if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0))
- {
- float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f;
- float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f;
-
- float bg_uv_left = 0.0f;
- float bg_uv_right = 1.0f;
- float bg_uv_top = 1.0f;
- float bg_uv_bottom = 0.0f;
-
- float bg_left = left;
- float bg_right = right;
- float bg_top = top;
- float bg_bottom = bottom;
- float bg_width = right - left;
- float bg_height = top - bottom;
- float bg_min_size = std::min(bg_width, bg_height);
-
- float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width;
- float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width;
- float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height;
- float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height;
-
- float bg_i_left = bg_left + scaled_border;
- float bg_i_right = bg_right - scaled_border;
- float bg_i_top = bg_top - scaled_border;
- float bg_i_bottom = bg_bottom + scaled_border;
-
- bg_uv_left = bg_uv_i_left;
- bg_i_left = bg_left;
-
- if ((m_overlay_border > 0) && (bg_uv_top != bg_uv_i_top))
- {
- if (bg_uv_left != bg_uv_i_left)
- GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } });
-
- GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } });
-
- if (bg_uv_right != bg_uv_i_right)
- GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } });
- }
-
- if ((m_overlay_border > 0) && (bg_uv_left != bg_uv_i_left))
- GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } });
-
- GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } });
-
- if ((m_overlay_border > 0) && (bg_uv_right != bg_uv_i_right))
- GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } });
-
- if ((m_overlay_border > 0) && (bg_uv_bottom != bg_uv_i_bottom))
- {
- if (bg_uv_left != bg_uv_i_left)
- GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } });
-
- GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } });
-
- if (bg_uv_right != bg_uv_i_right)
- GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } });
- }
- }
-
-#if ENABLE_SVG_ICONS
- top_x += scaled_border;
- top_y -= scaled_border;
- float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom;
-
- float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom;
- float scaled_stride_y = scaled_icons_size + scaled_gap_y;
- unsigned int icons_texture_id = m_icons_texture.get_id();
- unsigned int tex_width = m_icons_texture.get_width();
- unsigned int tex_height = m_icons_texture.get_height();
- float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f;
- float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f;
-#else
- top_x += m_overlay_border * inv_zoom;
- top_y -= m_overlay_border * inv_zoom;
- float scaled_gap_y = m_overlay_gap_y * inv_zoom;
-
- float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom;
- unsigned int icons_texture_id = m_icons_texture.texture.get_id();
- unsigned int texture_size = m_icons_texture.texture.get_width();
- float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
-#endif // ENABLE_SVG_ICONS
-
-#if ENABLE_SVG_ICONS
- if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0))
- return;
-#endif // ENABLE_SVG_ICONS
-
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
- unsigned int sprite_id = it->second->get_sprite_id();
- GLGizmoBase::EState state = it->second->get_state();
-
-#if ENABLE_SVG_ICONS
- float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width;
- float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height;
- float v_top = sprite_id * v_icon_size;
- float u_left = state * u_icon_size;
- float v_bottom = v_top + v_icon_size;
- float u_right = u_left + u_icon_size;
-#else
- float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size;
- float v_top = sprite_id * uv_icon_size;
- float u_left = state * uv_icon_size;
- float v_bottom = v_top + uv_icon_size;
- float u_right = u_left + uv_icon_size;
-#endif // ENABLE_SVG_ICONS
-
- GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
- if (it->second->get_state() == GLGizmoBase::On) {
- float toolbar_top = (float)cnv_h - canvas.m_view_toolbar.get_height();
-#if ENABLE_SVG_ICONS
- it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection);
-#else
- it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection);
-#endif // ENABLE_SVG_ICONS
- }
-#if ENABLE_SVG_ICONS
- top_y -= scaled_stride_y;
-#else
- top_y -= (scaled_icons_size + scaled_gap_y);
-#endif // ENABLE_SVG_ICONS
- }
-}
-
-void GLCanvas3D::Gizmos::do_render_current_gizmo(const Selection& selection) const
-{
- GLGizmoBase* curr = get_current();
- if (curr != nullptr)
- curr->render(selection);
-}
-
-float GLCanvas3D::Gizmos::get_total_overlay_height() const
-{
-#if ENABLE_SVG_ICONS
- float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
- float scaled_border = m_overlay_border * m_overlay_scale;
- float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
- float scaled_stride_y = scaled_icons_size + scaled_gap_y;
- float height = 2.0f * scaled_border;
-#else
- float height = 2.0f * m_overlay_border;
-
- float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
-#endif // ENABLE_SVG_ICONS
-
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if ((it->second == nullptr) || !it->second->is_selectable())
- continue;
-
-#if ENABLE_SVG_ICONS
- height += scaled_stride_y;
-#else
- height += (scaled_icons_size + m_overlay_gap_y);
-#endif // ENABLE_SVG_ICONS
- }
-
-#if ENABLE_SVG_ICONS
- return height - scaled_gap_y;
-#else
- return height - m_overlay_gap_y;
-#endif // ENABLE_SVG_ICONS
-}
-
-float GLCanvas3D::Gizmos::get_total_overlay_width() const
-{
-#if ENABLE_SVG_ICONS
- return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale;
-#else
- return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border;
-#endif // ENABLE_SVG_ICONS
-}
-
-GLGizmoBase* GLCanvas3D::Gizmos::get_current() const
-{
- GizmosMap::const_iterator it = m_gizmos.find(m_current);
- return (it != m_gizmos.end()) ? it->second : nullptr;
-}
-
-#if ENABLE_SVG_ICONS
-bool GLCanvas3D::Gizmos::generate_icons_texture() const
-{
- std::string path = resources_dir() + "/icons/";
- std::vector filenames;
- for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
- {
- if (it->second != nullptr)
- {
- const std::string& icon_filename = it->second->get_icon_filename();
- if (!icon_filename.empty())
- filenames.push_back(path + icon_filename);
- }
- }
-
- std::vector> states;
- states.push_back(std::make_pair(1, false));
- states.push_back(std::make_pair(0, false));
- states.push_back(std::make_pair(0, true));
-
- bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
- if (res)
- m_icons_texture_dirty = false;
-
- return res;
-}
-#endif // ENABLE_SVG_ICONS
-
const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 120, 120, 120 };//{ 9, 91, 134 };
const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
@@ -1794,14 +838,14 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL
}
// sends buffer to gpu
- ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- ::glGenTextures(1, &m_id);
- ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ glsafe(::glGenTextures(1, &m_id));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
@@ -1813,12 +857,12 @@ 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))
{
- ::glDisable(GL_DEPTH_TEST);
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glDisable(GL_DEPTH_TEST));
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
const Size& cnv_size = canvas.get_canvas_size();
- float zoom = canvas.get_camera_zoom();
+ float zoom = canvas.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
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;
@@ -1838,8 +882,8 @@ void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
- ::glPopMatrix();
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glPopMatrix());
+ glsafe(::glEnable(GL_DEPTH_TEST));
}
}
@@ -2066,14 +1110,14 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
}
// sends buffer to gpu
- ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- ::glGenTextures(1, &m_id);
- ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+ glsafe(::glGenTextures(1, &m_id));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
return true;
}
@@ -2082,12 +1126,12 @@ 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))
{
- ::glDisable(GL_DEPTH_TEST);
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glDisable(GL_DEPTH_TEST));
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
const Size& cnv_size = canvas.get_canvas_size();
- float zoom = canvas.get_camera_zoom();
+ float zoom = canvas.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
@@ -2107,8 +1151,8 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
- ::glPopMatrix();
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glPopMatrix());
+ glsafe(::glEnable(GL_DEPTH_TEST));
}
}
@@ -2198,48 +1242,48 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
if ((m_canvas == nullptr) || (m_context == nullptr))
return false;
- ::glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- ::glClearDepth(1.0f);
+ glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f));
+ glsafe(::glClearDepth(1.0f));
- ::glDepthFunc(GL_LESS);
+ glsafe(::glDepthFunc(GL_LESS));
- ::glEnable(GL_DEPTH_TEST);
- ::glEnable(GL_CULL_FACE);
- ::glEnable(GL_BLEND);
- ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glsafe(::glEnable(GL_DEPTH_TEST));
+ glsafe(::glEnable(GL_CULL_FACE));
+ glsafe(::glEnable(GL_BLEND));
+ glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
// Set antialiasing / multisampling
- ::glDisable(GL_LINE_SMOOTH);
- ::glDisable(GL_POLYGON_SMOOTH);
+ glsafe(::glDisable(GL_LINE_SMOOTH));
+ glsafe(::glDisable(GL_POLYGON_SMOOTH));
// ambient lighting
GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
- ::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+ glsafe(::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient));
- ::glEnable(GL_LIGHT0);
- ::glEnable(GL_LIGHT1);
+ glsafe(::glEnable(GL_LIGHT0));
+ glsafe(::glEnable(GL_LIGHT1));
// light from camera
GLfloat specular_cam[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
- ::glLightfv(GL_LIGHT1, GL_SPECULAR, specular_cam);
+ glsafe(::glLightfv(GL_LIGHT1, GL_SPECULAR, specular_cam));
GLfloat diffuse_cam[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
- ::glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_cam);
+ glsafe(::glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_cam));
// light from above
GLfloat specular_top[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
- ::glLightfv(GL_LIGHT0, GL_SPECULAR, specular_top);
+ glsafe(::glLightfv(GL_LIGHT0, GL_SPECULAR, specular_top));
GLfloat diffuse_top[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
- ::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_top);
+ glsafe(::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_top));
// Enables Smooth Color Shading; try GL_FLAT for (lack of) fun.
- ::glShadeModel(GL_SMOOTH);
+ glsafe(::glShadeModel(GL_SMOOTH));
// A handy trick -- have surface material mirror the color.
- ::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- ::glEnable(GL_COLOR_MATERIAL);
+ glsafe(::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE));
+ glsafe(::glEnable(GL_COLOR_MATERIAL));
if (m_multisample_allowed)
- ::glEnable(GL_MULTISAMPLE);
+ glsafe(::glEnable(GL_MULTISAMPLE));
if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs"))
return false;
@@ -2371,11 +1415,6 @@ void GLCanvas3D::set_color_by(const std::string& value)
m_color_by = value;
}
-float GLCanvas3D::get_camera_zoom() const
-{
- return m_camera.zoom;
-}
-
BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
{
BoundingBoxf3 bb;
@@ -2489,30 +1528,8 @@ void GLCanvas3D::zoom_to_selection()
void GLCanvas3D::select_view(const std::string& direction)
{
- const float* dir_vec = nullptr;
-
- if (direction == "iso")
- dir_vec = VIEW_DEFAULT;
- else if (direction == "left")
- dir_vec = VIEW_LEFT;
- else if (direction == "right")
- dir_vec = VIEW_RIGHT;
- else if (direction == "top")
- dir_vec = VIEW_TOP;
- else if (direction == "bottom")
- dir_vec = VIEW_BOTTOM;
- else if (direction == "front")
- dir_vec = VIEW_FRONT;
- else if (direction == "rear")
- dir_vec = VIEW_REAR;
-
- if (dir_vec != nullptr)
- {
- m_camera.phi = dir_vec[0];
- m_camera.set_theta(dir_vec[1], false);
- if (m_canvas != nullptr)
- m_canvas->Refresh();
- }
+ if (m_camera.select_view(direction) && (m_canvas != nullptr))
+ m_canvas->Refresh();
}
void GLCanvas3D::update_volumes_colors_by_extruder()
@@ -2556,12 +1573,12 @@ void GLCanvas3D::render()
m_camera.requires_zoom_to_bed = false;
}
- _camera_tranform();
+ m_camera.apply_view_matrix();
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
- ::glLightfv(GL_LIGHT1, GL_POSITION, position_cam);
+ glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
GLfloat position_top[4] = { -0.5f, -0.5f, 1.0f, 0.0f };
- ::glLightfv(GL_LIGHT0, GL_POSITION, position_top);
+ glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top));
float theta = m_camera.get_theta();
if (theta > 180.f)
@@ -2574,7 +1591,7 @@ void GLCanvas3D::render()
_picking_pass();
// draw scene
- ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_background();
// textured bed needs to be rendered after objects if the texture is transparent
@@ -2969,7 +1986,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
m_selection.volumes_changed(map_glvolume_old_to_new);
}
- _update_gizmos_data();
+ m_gizmos.update_data(*this);
// Update the toolbar
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
@@ -3194,6 +2211,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
return;
}
+ if (m_gizmos.on_char(evt, *this))
+ return;
+
//#ifdef __APPLE__
// ctrlMask |= wxMOD_RAW_CONTROL;
//#endif /* __APPLE__ */
@@ -3202,9 +2222,6 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'a':
case 'A':
case WXK_CONTROL_A:
- if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::SelectAll)) // Sla gizmo selects all support points
- m_dirty = true;
- else
post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL));
break;
#ifdef __APPLE__
@@ -3220,29 +2237,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
} else {
switch (keyCode)
{
- // key ESC
- case WXK_ESCAPE: {
- if (m_gizmos.get_current_type() != Gizmos::SlaSupports || !m_gizmos.gizmo_event(SLAGizmoEventType::DiscardChanges))
- m_gizmos.reset_all_states();
- m_dirty = true;
- break;
- }
-
- case WXK_RETURN: {
- if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::ApplyChanges))
- m_dirty = true;
- break;
- }
-
#ifdef __APPLE__
case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
#else /* __APPLE__ */
case WXK_DELETE:
#endif /* __APPLE__ */
- if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Delete))
- m_dirty = true;
- else
- post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE));
+ post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE));
break;
case '0': { select_view("iso"); break; }
@@ -3256,15 +2256,7 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case '-': { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; }
case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; }
case 'A':
- case 'a': {
- if (m_gizmos.get_current_type() == Gizmos::SlaSupports) {
- if (m_gizmos.gizmo_event(SLAGizmoEventType::AutomaticGeneration))
- m_dirty = true;
- }
- else
- post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE));
- break;
- }
+ case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'B':
case 'b': { zoom_to_bed(); break; }
case 'I':
@@ -3273,23 +2265,9 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'o': { set_camera_zoom(-1.0f); break; }
case 'Z':
case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; }
- case 'M':
- case 'm': {
- if (m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::ManualEditing)) {
- m_dirty = true;
- break;
- }
- } // intentional fallthrough
default:
{
- if (m_gizmos.handle_shortcut(keyCode, m_selection))
- {
- _update_gizmos_data();
- m_dirty = true;
- }
- else
- evt.Skip();
-
+ evt.Skip();
break;
}
}
@@ -3303,18 +2281,22 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
auto imgui = wxGetApp().imgui();
if (imgui->update_key_data(evt)) {
render();
- } else
- if (evt.GetEventType() == wxEVT_KEY_UP) {
- if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) {
- // Enable switching between 3D and Preview with Tab
- // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux
- post_event(SimpleEvent(EVT_GLCANVAS_TAB));
- } else if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.gizmo_event(SLAGizmoEventType::ShiftUp)) {
- // shift has been just released - SLA gizmo might want to close rectangular selection.
- m_dirty = true;
+ }
+ else
+ {
+ if (!m_gizmos.on_key(evt, *this))
+ {
+ if (evt.GetEventType() == wxEVT_KEY_UP) {
+ if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) {
+ // Enable switching between 3D and Preview with Tab
+ // m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux
+ post_event(SimpleEvent(EVT_GLCANVAS_TAB));
+ }
+ }
+ else if (evt.GetEventType() == wxEVT_KEY_DOWN) {
+ m_tab_down = keyCode == WXK_TAB && !evt.HasAnyModifiers();
+ }
}
- } else if (evt.GetEventType() == wxEVT_KEY_DOWN) {
- m_tab_down = keyCode == WXK_TAB && !evt.HasAnyModifiers();
}
if (keyCode != WXK_TAB
@@ -3418,6 +2400,18 @@ std::string format_mouse_event_debug_message(const wxMouseEvent &evt)
void GLCanvas3D::on_mouse(wxMouseEvent& evt)
{
+ auto mouse_up_cleanup = [this](){
+ m_moving = false;
+ m_mouse.drag.move_volume_idx = -1;
+ m_mouse.set_start_position_3D_as_invalid();
+ m_mouse.set_start_position_2D_as_invalid();
+ m_mouse.dragging = false;
+ m_dirty = true;
+
+ if (m_canvas->HasCapture())
+ m_canvas->ReleaseMouse();
+ };
+
#if ENABLE_RETINA_GL
const float scale = m_retina_helper->get_scale_factor();
evt.SetX(evt.GetX() * scale);
@@ -3454,11 +2448,27 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
#endif /* SLIC3R_DEBUG_MOUSE_EVENTS */
}
- bool processed_by_toolbar = m_toolbar.on_mouse(evt, *this);
- processed_by_toolbar |= m_view_toolbar.on_mouse(evt, *this);
-
- if (processed_by_toolbar)
+ if (m_toolbar.on_mouse(evt, *this))
{
+ if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
+ mouse_up_cleanup();
+ m_mouse.set_start_position_3D_as_invalid();
+ return;
+ }
+
+ if (m_view_toolbar.on_mouse(evt, *this))
+ {
+ if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
+ mouse_up_cleanup();
+ m_mouse.set_start_position_3D_as_invalid();
+ return;
+ }
+
+ if (m_gizmos.on_mouse(evt, *this))
+ {
+ if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
+ mouse_up_cleanup();
+
m_mouse.set_start_position_3D_as_invalid();
return;
}
@@ -3469,7 +2479,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
int selected_object_idx = m_selection.get_object_idx();
int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
m_layers_editing.select_object(*m_model, layer_editing_object_idx);
- bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position);
if (m_mouse.drag.move_requires_threshold && m_mouse.is_move_start_threshold_position_2D_defined() && m_mouse.is_move_threshold_met(pos))
{
@@ -3511,10 +2520,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_mouse.position = Vec2d(-1.0, -1.0);
m_dirty = true;
}
- else if (evt.LeftDClick() && (m_gizmos.get_current_type() != Gizmos::Undefined))
- {
- m_mouse.ignore_up_event = true;
- }
else if (evt.LeftDown() || evt.RightDown())
{
// If user pressed left or right button we first check whether this happened
@@ -3539,35 +2544,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
}
- else if (!m_selection.is_empty() && gizmos_overlay_contains_mouse)
- {
- m_gizmos.update_on_off_state(*this, m_mouse.position, m_selection);
- _update_gizmos_data();
- m_dirty = true;
- }
- else if (evt.LeftDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::LeftDown, Vec2d(pos(0), pos(1)), evt.ShiftDown()))
- {
- // the gizmo got the event and took some action, there is no need to do anything more
- }
- else if (evt.LeftDown() && !m_selection.is_empty() && m_gizmos.grabber_contains_mouse())
- {
- _update_gizmos_data();
- m_selection.start_dragging();
- m_gizmos.start_dragging(m_selection);
-
- if (m_gizmos.get_current_type() == Gizmos::Flatten) {
- // Rotate the object so the normal points downward:
- m_selection.flattening_rotate(m_gizmos.get_flattening_normal());
- do_flatten();
- wxGetApp().obj_manipul()->update_settings_value(m_selection);
- }
-
- m_dirty = true;
- }
- else if ((selected_object_idx != -1) && evt.RightDown() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::RightDown))
- {
- // event was taken care of by the SlaSupports gizmo
- }
else
{
// Select volume in this 3D canvas.
@@ -3579,15 +2555,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (evt.LeftDown() && (m_hover_volume_id != -1))
{
bool already_selected = m_selection.contains_volume(m_hover_volume_id);
- bool shift_down = evt.ShiftDown();
+ bool ctrl_down = evt.CmdDown();
Selection::IndicesList curr_idxs = m_selection.get_volume_idxs();
- if (already_selected && shift_down)
+ if (already_selected && ctrl_down)
m_selection.remove(m_hover_volume_id);
else
{
- bool add_as_single = !already_selected && !shift_down;
+ bool add_as_single = !already_selected && !ctrl_down;
m_selection.add(m_hover_volume_id, add_as_single);
m_mouse.drag.move_requires_threshold = !already_selected;
if (already_selected)
@@ -3598,9 +2574,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (curr_idxs != m_selection.get_volume_idxs())
{
-
- m_gizmos.update_on_off_state(m_selection);
- _update_gizmos_data();
+ m_gizmos.refresh_on_off_state(m_selection);
+ m_gizmos.update_data(*this);
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
m_dirty = true;
}
@@ -3627,8 +2602,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
}
- else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown)
- && (m_mouse.drag.move_volume_idx != -1) && m_gizmos.get_current_type() != Gizmos::SlaSupports /* don't allow dragging objects with the Sla gizmo on */)
+ else if (evt.Dragging() && evt.LeftIsDown() && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1))
{
if (!m_mouse.drag.move_requires_threshold)
{
@@ -3651,11 +2625,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// vector from the starting position to the found intersection
Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
- // get the view matrix back from opengl
- GLfloat matrix[16];
- ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- Vec3d camera_right((double)matrix[0], (double)matrix[4], (double)matrix[8]);
- Vec3d camera_up((double)matrix[1], (double)matrix[5], (double)matrix[9]);
+ Vec3d camera_right = m_camera.get_dir_right();
+ Vec3d camera_up = m_camera.get_dir_up();
// finds projection of the vector along the camera axes
double projection_x = inters_vec.dot(camera_right);
@@ -3681,53 +2652,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
}
- else if (evt.Dragging() && m_gizmos.is_dragging())
- {
- if (!m_canvas->HasCapture())
- m_canvas->CaptureMouse();
-
- m_mouse.dragging = true;
- m_gizmos.update(mouse_ray(pos), m_selection, evt.ShiftDown(), &pos);
-
- switch (m_gizmos.get_current_type())
- {
- case Gizmos::Move:
- {
- // Apply new temporary offset
- m_selection.translate(m_gizmos.get_displacement());
- wxGetApp().obj_manipul()->update_settings_value(m_selection);
- break;
- }
- case Gizmos::Scale:
- {
- // Apply new temporary scale factors
- m_selection.scale(m_gizmos.get_scale(), evt.AltDown());
- wxGetApp().obj_manipul()->update_settings_value(m_selection);
- break;
- }
- case Gizmos::Rotate:
- {
- // Apply new temporary rotations
- TransformationType transformation_type(TransformationType::World_Relative_Joint);
- if (evt.AltDown())
- transformation_type.set_independent();
- m_selection.rotate(m_gizmos.get_rotation(), transformation_type);
- wxGetApp().obj_manipul()->update_settings_value(m_selection);
- break;
- }
- default:
- break;
- }
-
- m_dirty = true;
- }
- else if (evt.Dragging() && m_gizmos.get_current_type() == Gizmos::SlaSupports && m_gizmos.gizmo_event(SLAGizmoEventType::Dragging, Vec2d(pos(0), pos(1)), evt.ShiftDown()))
- {
- // the gizmo got the event and took some action, no need to do anything more here
- m_dirty = true;
- }
- // do not process dragging if the mouse is into any of the HUD elements
- else if (evt.Dragging() && !gizmos_overlay_contains_mouse)
+ else if (evt.Dragging())
{
m_mouse.dragging = true;
@@ -3773,13 +2698,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
_stop_timer();
m_layers_editing.accept_changes(*this);
}
- else if (evt.LeftUp() && m_gizmos.get_current_type() == Gizmos::SlaSupports && !m_gizmos.is_dragging()
- && !m_mouse.dragging)
- {
- // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither
- // object moving or selecting is suppressed in that case
- m_gizmos.gizmo_event(SLAGizmoEventType::LeftUp, Vec2d(pos(0), pos(1)), evt.ShiftDown());
- }
else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging)
{
m_regenerate_volumes = false;
@@ -3789,52 +2707,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// of the scene with the background processing data should be performed.
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
}
- else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.grabber_contains_mouse() && !m_gizmos.is_dragging()
- && !is_layers_editing_enabled())
+ else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !is_layers_editing_enabled())
{
// deselect and propagate event through callback
- if (!evt.ShiftDown() && m_picking_enabled && !m_mouse.ignore_up_event)
+ if (!evt.ShiftDown() && m_picking_enabled)
{
m_selection.clear();
m_selection.set_mode(Selection::Instance);
wxGetApp().obj_manipul()->update_settings_value(m_selection);
m_gizmos.reset_all_states();
- _update_gizmos_data();
+ m_gizmos.update_data(*this);
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
}
- m_mouse.ignore_up_event = false;
- }
- else if (evt.LeftUp() && m_gizmos.is_dragging())
- {
- switch (m_gizmos.get_current_type())
- {
- case Gizmos::Move:
- {
- m_regenerate_volumes = false;
- do_move();
- break;
- }
- case Gizmos::Scale:
- {
- do_scale();
- break;
- }
- case Gizmos::Rotate:
- {
- do_rotate();
- break;
- }
- default:
- break;
- }
- m_gizmos.stop_dragging();
- _update_gizmos_data();
-
- wxGetApp().obj_manipul()->update_settings_value(m_selection);
- // Let the platter know that the dragging finished, so a delayed refresh
- // of the scene with the background processing data should be performed.
- post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
- m_camera.set_scene_box(scene_bounding_box());
}
else if (evt.RightUp())
{
@@ -3847,13 +2731,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// if right clicking on volume, propagate event through callback (shows context menu)
if (m_volumes.volumes[m_hover_volume_id]->hover
&& !m_volumes.volumes[m_hover_volume_id]->is_wipe_tower // no context menu for the wipe tower
- && m_gizmos.get_current_type() != Gizmos::SlaSupports) // disable context menu when the gizmo is open
+ && m_gizmos.get_current_type() != GLGizmosManager::SlaSupports) // disable context menu when the gizmo is open
{
// forces the selection of the volume
m_selection.add(m_hover_volume_id);
- m_gizmos.update_on_off_state(m_selection);
+ m_gizmos.refresh_on_off_state(m_selection);
post_event(SimpleEvent(EVT_GLCANVAS_OBJECT_SELECT));
- _update_gizmos_data();
+ m_gizmos.update_data(*this);
wxGetApp().obj_manipul()->update_settings_value(m_selection);
// forces a frame render to update the view before the context menu is shown
render();
@@ -3868,25 +2752,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
- m_moving = false;
- m_mouse.drag.move_volume_idx = -1;
- m_mouse.set_start_position_3D_as_invalid();
- m_mouse.set_start_position_2D_as_invalid();
- m_mouse.dragging = false;
- m_dirty = true;
-
- if (m_canvas->HasCapture())
- m_canvas->ReleaseMouse();
+ mouse_up_cleanup();
}
else if (evt.Moving())
{
m_mouse.position = pos.cast();
std::string tooltip = "";
- // updates gizmos overlay
- tooltip = m_gizmos.update_hover_state(*this, m_mouse.position, m_selection);
- if (m_selection.is_empty())
- m_gizmos.reset_all_states();
+ if (tooltip.empty())
+ tooltip = m_gizmos.get_tooltip();
if (tooltip.empty())
tooltip = m_toolbar.get_tooltip();
@@ -3896,6 +2770,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
set_tooltip(tooltip);
+ // updates gizmos overlay
+ if (m_selection.is_empty())
+ m_gizmos.reset_all_states();
+
// Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over.
if (m_picking_enabled)
m_dirty = true;
@@ -4192,7 +3070,7 @@ void GLCanvas3D::do_mirror()
void GLCanvas3D::set_camera_zoom(float zoom)
{
zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f;
- zoom = get_camera_zoom() / (1.0f - zoom);
+ zoom = m_camera.zoom / (1.0f - zoom);
// Don't allow to zoom too far outside the scene.
float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box());
@@ -4209,8 +3087,8 @@ void GLCanvas3D::set_camera_zoom(float zoom)
void GLCanvas3D::update_gizmos_on_off_state()
{
set_as_dirty();
- _update_gizmos_data();
- m_gizmos.update_on_off_state(get_selection());
+ m_gizmos.update_data(*this);
+ m_gizmos.refresh_on_off_state(get_selection());
}
void GLCanvas3D::handle_sidebar_focus_event(const std::string& opt_key, bool focus_on)
@@ -4244,6 +3122,13 @@ void GLCanvas3D::update_ui_from_settings()
#endif
}
+Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
+{
+ float z0 = 0.0f;
+ float z1 = 1.0f;
+ return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
+}
+
bool GLCanvas3D::_is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@@ -4430,10 +3315,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
// ensures that this canvas is current
_set_current();
- ::glViewport(0, 0, w, h);
-
- ::glMatrixMode(GL_PROJECTION);
- ::glLoadIdentity();
+ m_camera.apply_viewport(0, 0, w, h);
const BoundingBoxf3& bbox = _max_bounding_box();
@@ -4443,7 +3325,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
{
float w2 = w;
float h2 = h;
- float two_zoom = 2.0f * get_camera_zoom();
+ float two_zoom = 2.0f * m_camera.zoom;
if (two_zoom != 0.0f)
{
float inv_two_zoom = 1.0f / two_zoom;
@@ -4453,7 +3335,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
// FIXME: calculate a tighter value for depth will improve z-fighting
float depth = 5.0f * (float)bbox.max_size();
- ::glOrtho(-w2, w2, -h2, h2, -depth, depth);
+ m_camera.apply_ortho_projection(-w2, w2, -h2, h2, -depth, depth);
break;
}
@@ -4486,8 +3368,6 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
}
}
- ::glMatrixMode(GL_MODELVIEW);
-
m_dirty = false;
}
@@ -4521,16 +3401,11 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co
// then calculates the vertices coordinate on this plane along the camera xy axes
// we need the view matrix, we let opengl calculate it (same as done in render())
- _camera_tranform();
+ m_camera.apply_view_matrix();
- // get the view matrix back from opengl
- GLfloat matrix[16];
- ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
-
- // camera axes
- Vec3d right((double)matrix[0], (double)matrix[4], (double)matrix[8]);
- Vec3d up((double)matrix[1], (double)matrix[5], (double)matrix[9]);
- Vec3d forward((double)matrix[2], (double)matrix[6], (double)matrix[10]);
+ Vec3d right = m_camera.get_dir_right();
+ Vec3d up = m_camera.get_dir_up();
+ Vec3d forward = m_camera.get_dir_forward();
Vec3d bb_min = bbox.min;
Vec3d bb_max = bbox.max;
@@ -4591,17 +3466,6 @@ void GLCanvas3D::_refresh_if_shown_on_screen()
}
}
-void GLCanvas3D::_camera_tranform() const
-{
- ::glMatrixMode(GL_MODELVIEW);
- ::glLoadIdentity();
-
- ::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch
- ::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw
- Vec3d target = -m_camera.get_target();
- ::glTranslated(target(0), target(1), target(2));
-}
-
void GLCanvas3D::_picking_pass() const
{
const Vec2d& pos = m_mouse.position;
@@ -4613,12 +3477,12 @@ void GLCanvas3D::_picking_pass() const
// Better to use software ray - casting on a bounding - box hierarchy.
if (m_multisample_allowed)
- ::glDisable(GL_MULTISAMPLE);
+ glsafe(::glDisable(GL_MULTISAMPLE));
- ::glDisable(GL_BLEND);
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_BLEND));
+ glsafe(::glEnable(GL_DEPTH_TEST));
- ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
::glClipPlane(GL_CLIP_PLANE0, (GLdouble*)m_camera_clipping_plane.get_data());
@@ -4629,7 +3493,7 @@ void GLCanvas3D::_picking_pass() const
m_gizmos.render_current_gizmo_for_picking_pass(m_selection);
if (m_multisample_allowed)
- ::glEnable(GL_MULTISAMPLE);
+ glsafe(::glEnable(GL_MULTISAMPLE));
int volume_id = -1;
@@ -4638,7 +3502,7 @@ void GLCanvas3D::_picking_pass() const
bool inside = (0 <= pos(0)) && (pos(0) < cnv_size.get_width()) && (0 <= pos(1)) && (pos(1) < cnv_size.get_height());
if (inside)
{
- ::glReadPixels(pos(0), cnv_size.get_height() - pos(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color);
+ glsafe(::glReadPixels(pos(0), cnv_size.get_height() - pos(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color));
volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256;
}
if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
@@ -4658,14 +3522,14 @@ void GLCanvas3D::_picking_pass() const
void GLCanvas3D::_render_background() const
{
- ::glPushMatrix();
- ::glLoadIdentity();
- ::glMatrixMode(GL_PROJECTION);
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
+ glsafe(::glMatrixMode(GL_PROJECTION));
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
// Draws a bottom to top gradient over the complete screen.
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
::glBegin(GL_QUADS);
if (m_dynamic_background_enabled && _is_any_volume_outside())
@@ -4683,13 +3547,13 @@ void GLCanvas3D::_render_background() const
::glVertex2f(1.0f, 1.0f);
::glVertex2f(-1.0f, 1.0f);
- ::glEnd();
+ glsafe(::glEnd());
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_DEPTH_TEST));
- ::glPopMatrix();
- ::glMatrixMode(GL_MODELVIEW);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
+ glsafe(::glMatrixMode(GL_MODELVIEW));
+ glsafe(::glPopMatrix());
}
void GLCanvas3D::_render_bed(float theta) const
@@ -4713,8 +3577,8 @@ void GLCanvas3D::_render_objects() const
if (m_volumes.empty())
return;
- ::glEnable(GL_LIGHTING);
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_LIGHTING));
+ glsafe(::glEnable(GL_DEPTH_TEST));
m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane();
@@ -4743,19 +3607,19 @@ void GLCanvas3D::_render_objects() const
m_shader.start_using();
if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
int object_id = m_layers_editing.last_object_id;
- m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, [object_id](const GLVolume &volume) {
+ m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, m_camera.get_view_matrix(), [object_id](const GLVolume &volume) {
// Which volume to paint without the layer height profile shader?
- return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
+ return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
});
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
m_layers_editing.render_volumes(*this, this->m_volumes);
} else {
// do not cull backfaces to show broken geometry, if any
- m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) {
+ m_volumes.render_VBOs(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);
});
}
- m_volumes.render_VBOs(GLVolumeCollection::Transparent, false);
+ m_volumes.render_VBOs(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
m_shader.stop_using();
}
else
@@ -4765,25 +3629,25 @@ void GLCanvas3D::_render_objects() const
if (m_use_clipping_planes)
{
- ::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data());
- ::glEnable(GL_CLIP_PLANE1);
- ::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data());
- ::glEnable(GL_CLIP_PLANE2);
+ glsafe(::glClipPlane(GL_CLIP_PLANE1, (GLdouble*)m_clipping_planes[0].get_data()));
+ glsafe(::glEnable(GL_CLIP_PLANE1));
+ glsafe(::glClipPlane(GL_CLIP_PLANE2, (GLdouble*)m_clipping_planes[1].get_data()));
+ glsafe(::glEnable(GL_CLIP_PLANE2));
}
// do not cull backfaces to show broken geometry, if any
- m_volumes.render_legacy(GLVolumeCollection::Opaque, m_picking_enabled, [this](const GLVolume& volume) {
- return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
- });
- m_volumes.render_legacy(GLVolumeCollection::Transparent, false);
+ m_volumes.render_legacy(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);
+ });
+ m_volumes.render_legacy(GLVolumeCollection::Transparent, false, m_camera.get_view_matrix());
::glDisable(GL_CLIP_PLANE0);
if (m_use_clipping_planes)
{
- ::glDisable(GL_CLIP_PLANE1);
- ::glDisable(GL_CLIP_PLANE2);
+ glsafe(::glDisable(GL_CLIP_PLANE1));
+ glsafe(::glDisable(GL_CLIP_PLANE2));
}
}
@@ -4828,16 +3692,16 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
static const GLfloat INV_255 = 1.0f / 255.0f;
if (!fake_colors)
- ::glEnable(GL_LIGHTING);
+ glsafe(::glEnable(GL_LIGHTING));
// do not cull backfaces to show broken geometry, if any
- ::glDisable(GL_CULL_FACE);
+ glsafe(::glDisable(GL_CULL_FACE));
- ::glEnable(GL_BLEND);
- ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glsafe(::glEnable(GL_BLEND));
+ glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
- ::glEnableClientState(GL_VERTEX_ARRAY);
- ::glEnableClientState(GL_NORMAL_ARRAY);
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
unsigned int volume_id = 0;
for (GLVolume* vol : m_volumes.volumes)
@@ -4848,12 +3712,12 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
unsigned int r = (volume_id & 0x000000FF) >> 0;
unsigned int g = (volume_id & 0x0000FF00) >> 8;
unsigned int b = (volume_id & 0x00FF0000) >> 16;
- ::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255);
+ glsafe(::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255));
}
else
{
vol->set_render_color();
- ::glColor4fv(vol->render_color);
+ glsafe(::glColor4fv(vol->render_color));
}
if ((!fake_colors || !vol->disabled) && (vol->composite_id.volume_id >= 0 || m_render_sla_auxiliaries))
@@ -4862,14 +3726,14 @@ void GLCanvas3D::_render_volumes(bool fake_colors) const
++volume_id;
}
- ::glDisableClientState(GL_NORMAL_ARRAY);
- ::glDisableClientState(GL_VERTEX_ARRAY);
- ::glDisable(GL_BLEND);
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glDisable(GL_BLEND));
- ::glEnable(GL_CULL_FACE);
+ glsafe(::glEnable(GL_CULL_FACE));
if (!fake_colors)
- ::glDisable(GL_LIGHTING);
+ glsafe(::glDisable(GL_LIGHTING));
}
void GLCanvas3D::_render_current_gizmo() const
@@ -4898,7 +3762,7 @@ void GLCanvas3D::_render_toolbar() const
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
- float zoom = get_camera_zoom();
+ float zoom = m_camera.zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation();
@@ -4961,7 +3825,7 @@ void GLCanvas3D::_render_view_toolbar() const
#endif // ENABLE_RETINA_GL
Size cnv_size = get_canvas_size();
- float zoom = get_camera_zoom();
+ float zoom = m_camera.zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
// places the toolbar on the bottom-left corner of the 3d scene
@@ -4983,9 +3847,9 @@ void GLCanvas3D::_render_camera_target() const
{
double half_length = 5.0;
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
- ::glLineWidth(2.0f);
+ glsafe(::glLineWidth(2.0f));
::glBegin(GL_LINES);
const Vec3d& target = m_camera.get_target();
// draw line for x axis
@@ -5000,7 +3864,7 @@ void GLCanvas3D::_render_camera_target() const
::glColor3f(0.0f, 0.0f, 1.0f);
::glVertex3d(target(0), target(1), target(2) - half_length);
::glVertex3d(target(0), target(1), target(2) + half_length);
- ::glEnd();
+ glsafe(::glEnd());
}
#endif // ENABLE_SHOW_CAMERA_TARGET
@@ -5093,33 +3957,33 @@ void GLCanvas3D::_render_sla_slices() const
{
for (const SLAPrintObject::Instance& inst : obj->instances())
{
- ::glPushMatrix();
- ::glTranslated(unscale(inst.shift.x()), unscale(inst.shift.y()), 0);
- ::glRotatef(Geometry::rad2deg(inst.rotation), 0.0, 0.0, 1.0);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(unscale(inst.shift.x()), unscale(inst.shift.y()), 0));
+ glsafe(::glRotatef(Geometry::rad2deg(inst.rotation), 0.0, 0.0, 1.0));
if (obj->is_left_handed())
// The polygons are mirrored by X.
- ::glScalef(-1.0, 1.0, 1.0);
- ::glEnableClientState(GL_VERTEX_ARRAY);
- ::glColor3f(1.0f, 0.37f, 0.0f);
+ glsafe(::glScalef(-1.0, 1.0, 1.0));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glColor3f(1.0f, 0.37f, 0.0f));
if (!bottom_obj_triangles.empty()) {
- ::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_obj_triangles.front().data());
- ::glDrawArrays(GL_TRIANGLES, 0, bottom_obj_triangles.size());
+ glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_obj_triangles.front().data()));
+ glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_obj_triangles.size()));
}
if (! top_obj_triangles.empty()) {
- ::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_obj_triangles.front().data());
- ::glDrawArrays(GL_TRIANGLES, 0, top_obj_triangles.size());
+ glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_obj_triangles.front().data()));
+ glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_obj_triangles.size()));
}
- ::glColor3f(1.0f, 0.0f, 0.37f);
+ glsafe(::glColor3f(1.0f, 0.0f, 0.37f));
if (! bottom_sup_triangles.empty()) {
- ::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_sup_triangles.front().data());
- ::glDrawArrays(GL_TRIANGLES, 0, bottom_sup_triangles.size());
+ glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)bottom_sup_triangles.front().data()));
+ glsafe(::glDrawArrays(GL_TRIANGLES, 0, bottom_sup_triangles.size()));
}
if (! top_sup_triangles.empty()) {
- ::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_sup_triangles.front().data());
- ::glDrawArrays(GL_TRIANGLES, 0, top_sup_triangles.size());
+ glsafe(::glVertexPointer(3, GL_DOUBLE, 0, (GLdouble*)top_sup_triangles.front().data()));
+ glsafe(::glDrawArrays(GL_TRIANGLES, 0, top_sup_triangles.size()));
}
- ::glDisableClientState(GL_VERTEX_ARRAY);
- ::glPopMatrix();
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glPopMatrix());
}
}
}
@@ -5171,46 +4035,6 @@ void GLCanvas3D::_update_volumes_hover_state() const
}
}
-void GLCanvas3D::_update_gizmos_data()
-{
- if (!m_gizmos.is_enabled())
- return;
-
- bool enable_move_z = !m_selection.is_wipe_tower();
- m_gizmos.enable_grabber(Gizmos::Move, 2, enable_move_z);
- bool enable_scale_xyz = m_selection.is_single_full_instance() || m_selection.is_single_volume() || m_selection.is_single_modifier();
- for (int i = 0; i < 6; ++i)
- {
- m_gizmos.enable_grabber(Gizmos::Scale, i, enable_scale_xyz);
- }
-
- if (m_selection.is_single_full_instance())
- {
- // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
- const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()];
- m_gizmos.set_scale(volume->get_instance_scaling_factor());
- m_gizmos.set_rotation(Vec3d::Zero());
- ModelObject* model_object = m_model->objects[m_selection.get_object_idx()];
- m_gizmos.set_flattening_data(model_object);
- m_gizmos.set_sla_support_data(model_object, m_selection);
- }
- else if (m_selection.is_single_volume() || m_selection.is_single_modifier())
- {
- const GLVolume* volume = m_volumes.volumes[*m_selection.get_volume_idxs().begin()];
- m_gizmos.set_scale(volume->get_volume_scaling_factor());
- m_gizmos.set_rotation(Vec3d::Zero());
- m_gizmos.set_flattening_data(nullptr);
- m_gizmos.set_sla_support_data(nullptr, m_selection);
- }
- else
- {
- m_gizmos.set_scale(Vec3d::Ones());
- m_gizmos.set_rotation(Vec3d::Zero());
- m_gizmos.set_flattening_data(m_selection.is_from_single_object() ? m_model->objects[m_selection.get_object_idx()] : nullptr);
- m_gizmos.set_sla_support_data(nullptr, m_selection);
- }
-}
-
void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt)
{
int object_idx_selected = m_layers_editing.last_object_id;
@@ -5240,24 +4064,20 @@ Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z)
if (m_canvas == nullptr)
return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX);
- _camera_tranform();
- GLint viewport[4];
- ::glGetIntegerv(GL_VIEWPORT, viewport);
- GLdouble modelview_matrix[16];
- ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix);
- GLdouble projection_matrix[16];
- ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix);
+ const std::array& viewport = m_camera.get_viewport();
+ const Transform3d& modelview_matrix = m_camera.get_view_matrix();
+ const Transform3d& projection_matrix = m_camera.get_projection_matrix();
GLint y = viewport[3] - (GLint)mouse_pos(1);
GLfloat mouse_z;
if (z == nullptr)
- ::glReadPixels((GLint)mouse_pos(0), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z);
+ glsafe(::glReadPixels((GLint)mouse_pos(0), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z));
else
mouse_z = *z;
GLdouble out_x, out_y, out_z;
- ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z);
+ ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z);
return Vec3d((double)out_x, (double)out_y, (double)out_z);
}
@@ -5266,13 +4086,6 @@ Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos)
return mouse_ray(mouse_pos).intersect_plane(0.0);
}
-Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
-{
- float z0 = 0.0f;
- float z1 = 1.0f;
- return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
-}
-
void GLCanvas3D::_start_timer()
{
m_timer.Start(100, wxTIMER_CONTINUOUS);
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 656b6e2294..ef128bae45 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -10,6 +10,7 @@
#include "3DBed.hpp"
#include "Camera.hpp"
#include "Selection.hpp"
+#include "Gizmos/GLGizmosManager.hpp"
#include
@@ -64,33 +65,35 @@ public:
void set_scale_factor(int height);
};
-class Rect
+
+class ClippingPlane
{
- float m_left;
- float m_top;
- float m_right;
- float m_bottom;
+ double m_data[4];
public:
- Rect();
- Rect(float left, float top, float right, float bottom);
+ ClippingPlane()
+ {
+ m_data[0] = 0.0;
+ m_data[1] = 0.0;
+ m_data[2] = 1.0;
+ m_data[3] = 0.0;
+ }
- float get_left() const;
- void set_left(float left);
+ ClippingPlane(const Vec3d& direction, double offset)
+ {
+ Vec3d norm_dir = direction.normalized();
+ m_data[0] = norm_dir(0);
+ m_data[1] = norm_dir(1);
+ m_data[2] = norm_dir(2);
+ m_data[3] = offset;
+ }
- float get_top() const;
- void set_top(float top);
+ static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); }
- float get_right() const;
- void set_right(float right);
-
- float get_bottom() const;
- void set_bottom(float bottom);
-
- float get_width() const { return m_right - m_left; }
- float get_height() const { return m_top - m_bottom; }
+ const double* get_data() const { return m_data; }
};
+
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
using Vec2dEvent = Event;
@@ -118,22 +121,6 @@ wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent);
-// this describes events being passed from GLCanvas3D to SlaSupport gizmo
-enum class SLAGizmoEventType {
- LeftDown = 1,
- LeftUp,
- RightDown,
- Dragging,
- Delete,
- SelectAll,
- ShiftUp,
- ApplyChanges,
- DiscardChanges,
- AutomaticGeneration,
- ManualEditing
-};
-
-
class GLCanvas3D
{
struct GCodePreviewVolumeIndex
@@ -314,7 +301,6 @@ class GLCanvas3D
Vec2d position;
Vec3d scene_position;
Drag drag;
- bool ignore_up_event;
Mouse();
@@ -331,148 +317,7 @@ class GLCanvas3D
}
};
-public:
- class ClippingPlane
- {
- double m_data[4];
-
- public:
- ClippingPlane()
- {
- m_data[0] = 0.0;
- m_data[1] = 0.0;
- m_data[2] = 1.0;
- m_data[3] = 0.0;
- }
-
- ClippingPlane(const Vec3d& direction, double offset)
- {
- Vec3d norm_dir = direction.normalized();
- m_data[0] = norm_dir(0);
- m_data[1] = norm_dir(1);
- m_data[2] = norm_dir(2);
- m_data[3] = offset;
- }
-
- static ClippingPlane ClipsNothing() { return ClippingPlane(Vec3d(0., 0., 1.), DBL_MAX); }
-
- const double* get_data() const { return m_data; }
- };
-
private:
- class Gizmos
- {
- public:
-#if ENABLE_SVG_ICONS
- static const float Default_Icons_Size;
-#endif // ENABLE_SVG_ICONS
-
- enum EType : unsigned char
- {
- Undefined,
- Move,
- Scale,
- Rotate,
- Flatten,
- Cut,
- SlaSupports,
- Num_Types
- };
-
- private:
- bool m_enabled;
- typedef std::map GizmosMap;
- GizmosMap m_gizmos;
-#if ENABLE_SVG_ICONS
- mutable GLTexture m_icons_texture;
- mutable bool m_icons_texture_dirty;
-#else
- ItemsIconsTexture m_icons_texture;
-#endif // ENABLE_SVG_ICONS
- BackgroundTexture m_background_texture;
- EType m_current;
-
-#if ENABLE_SVG_ICONS
- float m_overlay_icons_size;
- float m_overlay_scale;
-#else
- float m_overlay_icons_scale;
-#endif // ENABLE_SVG_ICONS
- float m_overlay_border;
- float m_overlay_gap_y;
-
- public:
- Gizmos();
- ~Gizmos();
-
- bool init(GLCanvas3D& parent);
-
- bool is_enabled() const;
- void set_enabled(bool enable);
-
-#if ENABLE_SVG_ICONS
- void set_overlay_icon_size(float size);
-#endif // ENABLE_SVG_ICONS
- void set_overlay_scale(float scale);
-
- std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection);
- void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection);
- void update_on_off_state(const Selection& selection);
- void reset_all_states();
-
- void set_hover_id(int id);
- void enable_grabber(EType type, unsigned int id, bool enable);
-
- bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const;
- bool grabber_contains_mouse() const;
- void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr);
- Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const;
- EType get_current_type() const;
-
- bool is_running() const;
- bool handle_shortcut(int key, const Selection& selection);
-
- bool is_dragging() const;
- void start_dragging(const Selection& selection);
- void stop_dragging();
-
- Vec3d get_displacement() const;
-
- Vec3d get_scale() const;
- void set_scale(const Vec3d& scale);
-
- Vec3d get_rotation() const;
- void set_rotation(const Vec3d& rotation);
-
- Vec3d get_flattening_normal() const;
-
- void set_flattening_data(const ModelObject* model_object);
-
- void set_sla_support_data(ModelObject* model_object, const Selection& selection);
- bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false);
- ClippingPlane get_sla_clipping_plane() const;
-
- void render_current_gizmo(const Selection& selection) const;
- void render_current_gizmo_for_picking_pass(const Selection& selection) const;
-
- void render_overlay(const GLCanvas3D& canvas, const Selection& selection) const;
-
- private:
- void reset();
-
- void do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const;
- void do_render_current_gizmo(const Selection& selection) const;
-
- float get_total_overlay_height() const;
- float get_total_overlay_width() const;
-
- GLGizmoBase* get_current() const;
-
-#if ENABLE_SVG_ICONS
- bool generate_icons_texture() const;
-#endif // ENABLE_SVG_ICONS
- };
-
struct SlaCap
{
struct Triangles
@@ -560,7 +405,7 @@ private:
LayersEditing m_layers_editing;
Shader m_shader;
Mouse m_mouse;
- mutable Gizmos m_gizmos;
+ mutable GLGizmosManager m_gizmos;
mutable GLToolbar m_toolbar;
ClippingPlane m_clipping_planes[2];
mutable ClippingPlane m_camera_clipping_plane;
@@ -643,7 +488,7 @@ public:
void set_color_by(const std::string& value);
- float get_camera_zoom() const;
+ const Camera& get_camera() const { return m_camera; }
BoundingBoxf3 volumes_bounding_box() const;
BoundingBoxf3 scene_bounding_box() const;
@@ -725,6 +570,19 @@ public:
void update_ui_from_settings();
+ float get_view_toolbar_height() const { return m_view_toolbar.get_height(); }
+
+ int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; }
+ int get_hover_volume_id() const { return m_hover_volume_id; }
+
+ // Returns the view ray line, in world coordinate, at the given mouse position.
+ Linef3 mouse_ray(const Point& mouse_pos);
+
+ void set_mouse_as_dragging() { m_mouse.dragging = true; }
+ void disable_regenerate_volumes() { m_regenerate_volumes = false; }
+ void refresh_camera_scene_box() { m_camera.set_scene_box(scene_bounding_box()); }
+ bool is_mouse_dragging() const { return m_mouse.dragging; }
+
private:
bool _is_shown_on_screen() const;
@@ -740,7 +598,6 @@ private:
void _refresh_if_shown_on_screen();
- void _camera_tranform() const;
void _picking_pass() const;
void _render_background() const;
void _render_bed(float theta) const;
@@ -764,7 +621,6 @@ private:
void _render_selection_sidebar_hints() const;
void _update_volumes_hover_state() const;
- void _update_gizmos_data();
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
@@ -775,9 +631,6 @@ private:
// Convert the screen space coordinate to world coordinate on the bed.
Vec3d _mouse_to_bed_3d(const Point& mouse_pos);
- // Returns the view ray line, in world coordinate, at the given mouse position.
- Linef3 mouse_ray(const Point& mouse_pos);
-
void _start_timer();
void _stop_timer();
diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp
index f401f54662..7f3bc0893a 100644
--- a/src/slic3r/GUI/GLShader.cpp
+++ b/src/slic3r/GUI/GLShader.cpp
@@ -3,6 +3,7 @@
#include "GLShader.hpp"
#include "libslic3r/Utils.hpp"
+#include "3DScene.hpp"
#include
#include
@@ -52,21 +53,22 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh
}
if (fragment_shader != nullptr) {
- this->fragment_program_id = glCreateShader(GL_FRAGMENT_SHADER);
+ this->fragment_program_id = ::glCreateShader(GL_FRAGMENT_SHADER);
+ glcheck();
if (this->fragment_program_id == 0) {
last_error = "glCreateShader(GL_FRAGMENT_SHADER) failed.";
return false;
}
GLint len = (GLint)strlen(fragment_shader);
- glShaderSource(this->fragment_program_id, 1, &fragment_shader, &len);
- glCompileShader(this->fragment_program_id);
+ glsafe(::glShaderSource(this->fragment_program_id, 1, &fragment_shader, &len));
+ glsafe(::glCompileShader(this->fragment_program_id));
GLint params;
- glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, ¶ms);
+ glsafe(::glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, ¶ms));
if (params == GL_FALSE) {
// Compilation failed. Get the log.
- glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, ¶ms);
+ glsafe(::glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, ¶ms));
std::vector msg(params);
- glGetShaderInfoLog(this->fragment_program_id, params, ¶ms, msg.data());
+ glsafe(::glGetShaderInfoLog(this->fragment_program_id, params, ¶ms, msg.data()));
this->last_error = std::string("Fragment shader compilation failed:\n") + msg.data();
this->release();
return false;
@@ -74,22 +76,23 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh
}
if (vertex_shader != nullptr) {
- this->vertex_program_id = glCreateShader(GL_VERTEX_SHADER);
+ this->vertex_program_id = ::glCreateShader(GL_VERTEX_SHADER);
+ glcheck();
if (this->vertex_program_id == 0) {
last_error = "glCreateShader(GL_VERTEX_SHADER) failed.";
this->release();
return false;
}
GLint len = (GLint)strlen(vertex_shader);
- glShaderSource(this->vertex_program_id, 1, &vertex_shader, &len);
- glCompileShader(this->vertex_program_id);
+ glsafe(::glShaderSource(this->vertex_program_id, 1, &vertex_shader, &len));
+ glsafe(::glCompileShader(this->vertex_program_id));
GLint params;
- glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, ¶ms);
+ glsafe(::glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, ¶ms));
if (params == GL_FALSE) {
// Compilation failed. Get the log.
- glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms);
+ glsafe(::glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms));
std::vector msg(params);
- glGetShaderInfoLog(this->vertex_program_id, params, ¶ms, msg.data());
+ glsafe(::glGetShaderInfoLog(this->vertex_program_id, params, ¶ms, msg.data()));
this->last_error = std::string("Vertex shader compilation failed:\n") + msg.data();
this->release();
return false;
@@ -97,7 +100,8 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh
}
// Link shaders
- this->shader_program_id = glCreateProgram();
+ this->shader_program_id = ::glCreateProgram();
+ glcheck();
if (this->shader_program_id == 0) {
last_error = "glCreateProgram() failed.";
this->release();
@@ -105,18 +109,18 @@ bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_sh
}
if (this->fragment_program_id)
- glAttachShader(this->shader_program_id, this->fragment_program_id);
+ glsafe(::glAttachShader(this->shader_program_id, this->fragment_program_id));
if (this->vertex_program_id)
- glAttachShader(this->shader_program_id, this->vertex_program_id);
- glLinkProgram(this->shader_program_id);
+ glsafe(::glAttachShader(this->shader_program_id, this->vertex_program_id));
+ glsafe(::glLinkProgram(this->shader_program_id));
GLint params;
- glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, ¶ms);
+ glsafe(::glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, ¶ms));
if (params == GL_FALSE) {
// Linking failed. Get the log.
- glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms);
+ glsafe(::glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, ¶ms));
std::vector msg(params);
- glGetProgramInfoLog(this->vertex_program_id, params, ¶ms, msg.data());
+ glsafe(::glGetProgramInfoLog(this->vertex_program_id, params, ¶ms, msg.data()));
this->last_error = std::string("Shader linking failed:\n") + msg.data();
this->release();
return false;
@@ -165,31 +169,31 @@ void GLShader::release()
{
if (this->shader_program_id) {
if (this->vertex_program_id)
- glDetachShader(this->shader_program_id, this->vertex_program_id);
+ glsafe(::glDetachShader(this->shader_program_id, this->vertex_program_id));
if (this->fragment_program_id)
- glDetachShader(this->shader_program_id, this->fragment_program_id);
- glDeleteProgram(this->shader_program_id);
+ glsafe(::glDetachShader(this->shader_program_id, this->fragment_program_id));
+ glsafe(::glDeleteProgram(this->shader_program_id));
this->shader_program_id = 0;
}
if (this->vertex_program_id) {
- glDeleteShader(this->vertex_program_id);
+ glsafe(::glDeleteShader(this->vertex_program_id));
this->vertex_program_id = 0;
}
if (this->fragment_program_id) {
- glDeleteShader(this->fragment_program_id);
+ glsafe(::glDeleteShader(this->fragment_program_id));
this->fragment_program_id = 0;
}
}
void GLShader::enable() const
{
- glUseProgram(this->shader_program_id);
+ glsafe(::glUseProgram(this->shader_program_id));
}
void GLShader::disable() const
{
- glUseProgram(0);
+ glsafe(::glUseProgram(0));
}
// Return shader vertex attribute ID
@@ -208,7 +212,7 @@ bool GLShader::set_uniform(const char *name, float value) const
{
int id = this->get_uniform_location(name);
if (id >= 0) {
- glUniform1fARB(id, value);
+ glsafe(::glUniform1fARB(id, value));
return true;
}
return false;
@@ -219,7 +223,7 @@ bool GLShader::set_uniform(const char* name, const float* matrix) const
int id = get_uniform_location(name);
if (id >= 0)
{
- ::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix);
+ glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix));
return true;
}
return false;
@@ -230,7 +234,7 @@ bool GLShader::set_uniform(const char* name, int value) const
int id = get_uniform_location(name);
if (id >= 0)
{
- ::glUniform1i(id, value);
+ glsafe(::glUniform1i(id, value));
return true;
}
return false;
diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp
index 68369d9d03..2fff0869ad 100644
--- a/src/slic3r/GUI/GLTexture.cpp
+++ b/src/slic3r/GUI/GLTexture.cpp
@@ -1,6 +1,8 @@
#include "libslic3r/libslic3r.h"
#include "GLTexture.hpp"
+#include "3DScene.hpp"
+
#include
#include
@@ -173,15 +175,15 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vectoris_separator())
{
// mouse is inside an icon
do_action((unsigned int)item_id, parent);
- processed = true;
}
}
else if (evt.MiddleDown())
@@ -612,7 +612,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
{
// NB: mouse_pos is already scaled appropriately
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = m_layout.scale * inv_zoom;
@@ -717,7 +717,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
{
// NB: mouse_pos is already scaled appropriately
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = m_layout.scale * inv_zoom;
@@ -834,7 +834,7 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
{
// NB: mouse_pos is already scaled appropriately
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = m_layout.scale * inv_zoom;
@@ -917,7 +917,7 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
{
// NB: mouse_pos is already scaled appropriately
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = m_layout.scale * inv_zoom;
@@ -1013,7 +1013,7 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
return;
#endif // !ENABLE_SVG_ICONS
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = inv_zoom * m_layout.scale;
@@ -1168,7 +1168,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
return;
#endif // !ENABLE_SVG_ICONS
- float zoom = parent.get_camera_zoom();
+ float zoom = parent.get_camera().zoom;
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
#if ENABLE_SVG_ICONS
float factor = inv_zoom * m_layout.scale;
diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp
index 5fac1f5b2e..0f8b17e04f 100644
--- a/src/slic3r/GUI/GLToolbar.hpp
+++ b/src/slic3r/GUI/GLToolbar.hpp
@@ -7,6 +7,7 @@
#include "GLTexture.hpp"
#include "Event.hpp"
+#include "libslic3r/Point.hpp"
class wxEvtHandler;
diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp
index 438e9d236a..206253451a 100644
--- a/src/slic3r/GUI/GUI_Preview.cpp
+++ b/src/slic3r/GUI/GUI_Preview.cpp
@@ -818,8 +818,8 @@ void Preview::on_sliders_scroll_changed(wxEvent& event)
}
else if (tech == ptSLA)
{
- m_canvas->set_clipping_plane(0, GLCanvas3D::ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD()));
- m_canvas->set_clipping_plane(1, GLCanvas3D::ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD()));
+ m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD()));
+ m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD()));
m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0);
m_canvas_widget->Refresh();
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
index a1e95cfc53..6bf43955fb 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
@@ -1,4 +1,5 @@
#include "GLGizmoBase.hpp"
+#include "slic3r/GUI/GLCanvas3D.hpp"
#include
@@ -60,62 +61,62 @@ void GLGizmoBase::Grabber::render(float size, const float* render_color, bool us
float half_size = dragging ? get_dragging_half_size(size) : get_half_size(size);
if (use_lighting)
- ::glEnable(GL_LIGHTING);
+ glsafe(::glEnable(GL_LIGHTING));
- ::glColor3fv(render_color);
+ glsafe(::glColor3fv(render_color));
- ::glPushMatrix();
- ::glTranslated(center(0), center(1), center(2));
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(center(0), center(1), center(2)));
- ::glRotated(Geometry::rad2deg(angles(2)), 0.0, 0.0, 1.0);
- ::glRotated(Geometry::rad2deg(angles(1)), 0.0, 1.0, 0.0);
- ::glRotated(Geometry::rad2deg(angles(0)), 1.0, 0.0, 0.0);
+ glsafe(::glRotated(Geometry::rad2deg(angles(2)), 0.0, 0.0, 1.0));
+ glsafe(::glRotated(Geometry::rad2deg(angles(1)), 0.0, 1.0, 0.0));
+ glsafe(::glRotated(Geometry::rad2deg(angles(0)), 1.0, 0.0, 0.0));
// face min x
- ::glPushMatrix();
- ::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f);
- ::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f));
+ glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
// face max x
- ::glPushMatrix();
- ::glTranslatef((GLfloat)half_size, 0.0f, 0.0f);
- ::glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef((GLfloat)half_size, 0.0f, 0.0f));
+ glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
// face min y
- ::glPushMatrix();
- ::glTranslatef(0.0f, -(GLfloat)half_size, 0.0f);
- ::glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.0f, -(GLfloat)half_size, 0.0f));
+ glsafe(::glRotatef(90.0f, 1.0f, 0.0f, 0.0f));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
// face max y
- ::glPushMatrix();
- ::glTranslatef(0.0f, (GLfloat)half_size, 0.0f);
- ::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.0f, (GLfloat)half_size, 0.0f));
+ glsafe(::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
// face min z
- ::glPushMatrix();
- ::glTranslatef(0.0f, 0.0f, -(GLfloat)half_size);
- ::glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.0f, 0.0f, -(GLfloat)half_size));
+ glsafe(::glRotatef(180.0f, 1.0f, 0.0f, 0.0f));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
// face max z
- ::glPushMatrix();
- ::glTranslatef(0.0f, 0.0f, (GLfloat)half_size);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.0f, 0.0f, (GLfloat)half_size));
render_face(half_size);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
if (use_lighting)
- ::glDisable(GL_LIGHTING);
+ glsafe(::glDisable(GL_LIGHTING));
}
void GLGizmoBase::Grabber::render_face(float half_size) const
@@ -128,7 +129,7 @@ void GLGizmoBase::Grabber::render_face(float half_size) const
::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f);
::glVertex3f(-(GLfloat)half_size, (GLfloat)half_size, 0.0f);
::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f);
- ::glEnd();
+ glsafe(::glEnd());
}
#if ENABLE_SVG_ICONS
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
index b70c1f8df1..461f655702 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
@@ -3,7 +3,6 @@
#include "libslic3r/Point.hpp"
-#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/Selection.hpp"
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
index 5eb0d05839..cabede8cd6 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
@@ -1,5 +1,6 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoCut.hpp"
+#include "slic3r/GUI/GLCanvas3D.hpp"
#include
@@ -135,10 +136,10 @@ void GLGizmoCut::on_render(const Selection& selection) const
const float max_x = box.max(0) + Margin;
const float min_y = box.min(1) - Margin;
const float max_y = box.max(1) + Margin;
- ::glEnable(GL_DEPTH_TEST);
- ::glDisable(GL_CULL_FACE);
- ::glEnable(GL_BLEND);
- ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glsafe(::glEnable(GL_DEPTH_TEST));
+ glsafe(::glDisable(GL_CULL_FACE));
+ glsafe(::glEnable(GL_BLEND));
+ glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
// Draw the cutting plane
::glBegin(GL_QUADS);
@@ -147,10 +148,10 @@ void GLGizmoCut::on_render(const Selection& selection) const
::glVertex3f(max_x, min_y, plane_center(2));
::glVertex3f(max_x, max_y, plane_center(2));
::glVertex3f(min_x, max_y, plane_center(2));
- ::glEnd();
+ glsafe(::glEnd());
- ::glEnable(GL_CULL_FACE);
- ::glDisable(GL_BLEND);
+ glsafe(::glEnable(GL_CULL_FACE));
+ glsafe(::glDisable(GL_BLEND));
// TODO: draw cut part contour?
@@ -158,13 +159,13 @@ void GLGizmoCut::on_render(const Selection& selection) const
m_grabbers[0].center = plane_center;
m_grabbers[0].center(2) = plane_center(2) + Offset;
- ::glDisable(GL_DEPTH_TEST);
- ::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f);
- ::glColor3f(1.0, 1.0, 0.0);
+ glsafe(::glDisable(GL_DEPTH_TEST));
+ glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
+ glsafe(::glColor3f(1.0, 1.0, 0.0));
::glBegin(GL_LINES);
::glVertex3dv(plane_center.data());
::glVertex3dv(m_grabbers[0].center.data());
- ::glEnd();
+ glsafe(::glEnd());
std::copy(std::begin(GrabberColor), std::end(GrabberColor), m_grabbers[0].color);
m_grabbers[0].render(m_hover_id == 0, (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0));
@@ -172,7 +173,7 @@ void GLGizmoCut::on_render(const Selection& selection) const
void GLGizmoCut::on_render_for_picking(const Selection& selection) const
{
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
render_grabbers_for_picking(selection.get_bounding_box());
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
index 2ed0486772..56dbf4f54f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
@@ -49,67 +49,67 @@ void GLGizmoFlatten::on_start_dragging(const Selection& selection)
void GLGizmoFlatten::on_render(const Selection& selection) const
{
- ::glClear(GL_DEPTH_BUFFER_BIT);
+ glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
- ::glEnable(GL_DEPTH_TEST);
- ::glEnable(GL_BLEND);
+ glsafe(::glEnable(GL_DEPTH_TEST));
+ glsafe(::glEnable(GL_BLEND));
if (selection.is_single_full_instance())
{
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
- ::glPushMatrix();
- ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z());
- ::glMultMatrixd(m.data());
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
+ glsafe(::glMultMatrixd(m.data()));
if (this->is_plane_update_necessary())
const_cast(this)->update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i)
{
if (i == m_hover_id)
- ::glColor4f(0.9f, 0.9f, 0.9f, 0.75f);
+ glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.75f));
else
- ::glColor4f(0.9f, 0.9f, 0.9f, 0.5f);
+ glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.5f));
::glBegin(GL_POLYGON);
for (const Vec3d& vertex : m_planes[i].vertices)
{
::glVertex3dv(vertex.data());
}
- ::glEnd();
+ glsafe(::glEnd());
}
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
- ::glEnable(GL_CULL_FACE);
- ::glDisable(GL_BLEND);
+ glsafe(::glEnable(GL_CULL_FACE));
+ glsafe(::glDisable(GL_BLEND));
}
void GLGizmoFlatten::on_render_for_picking(const Selection& selection) const
{
- ::glDisable(GL_DEPTH_TEST);
- ::glDisable(GL_BLEND);
+ glsafe(::glDisable(GL_DEPTH_TEST));
+ glsafe(::glDisable(GL_BLEND));
if (selection.is_single_full_instance())
{
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
- ::glPushMatrix();
- ::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z());
- ::glMultMatrixd(m.data());
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
+ glsafe(::glMultMatrixd(m.data()));
if (this->is_plane_update_necessary())
const_cast(this)->update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i)
{
- ::glColor3fv(picking_color_component(i).data());
+ glsafe(::glColor3fv(picking_color_component(i).data()));
::glBegin(GL_POLYGON);
for (const Vec3d& vertex : m_planes[i].vertices)
{
::glVertex3dv(vertex.data());
}
- ::glEnd();
+ glsafe(::glEnd());
}
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
- ::glEnable(GL_CULL_FACE);
+ glsafe(::glEnable(GL_CULL_FACE));
}
void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
index 61f219dbff..7cc5b6485b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
@@ -97,8 +97,8 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
else if (!m_grabbers[2].dragging && (m_hover_id == 2))
set_tooltip("Z");
- ::glClear(GL_DEPTH_BUFFER_BIT);
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
+ glsafe(::glEnable(GL_DEPTH_TEST));
const BoundingBoxf3& box = selection.get_bounding_box();
const Vec3d& center = box.center();
@@ -115,7 +115,7 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset);
::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float));
- ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
+ glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
if (m_hover_id == -1)
{
@@ -124,11 +124,11 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
{
if (m_grabbers[i].enabled)
{
- ::glColor3fv(AXES_COLOR[i]);
+ glsafe(::glColor3fv(AXES_COLOR[i]));
::glBegin(GL_LINES);
::glVertex3dv(center.data());
::glVertex3dv(m_grabbers[i].center.data());
- ::glEnd();
+ glsafe(::glEnd());
}
}
@@ -143,11 +143,11 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
else
{
// draw axis
- ::glColor3fv(AXES_COLOR[m_hover_id]);
+ glsafe(::glColor3fv(AXES_COLOR[m_hover_id]));
::glBegin(GL_LINES);
::glVertex3dv(center.data());
::glVertex3dv(m_grabbers[m_hover_id].center.data());
- ::glEnd();
+ glsafe(::glEnd());
// draw grabber
m_grabbers[m_hover_id].render(true, box.max_size());
@@ -157,7 +157,7 @@ void GLGizmoMove3D::on_render(const Selection& selection) const
void GLGizmoMove3D::on_render_for_picking(const Selection& selection) const
{
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
const BoundingBoxf3& box = selection.get_bounding_box();
render_grabbers_for_picking(box);
@@ -229,25 +229,25 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
}
if (!picking)
- ::glEnable(GL_LIGHTING);
+ glsafe(::glEnable(GL_LIGHTING));
- ::glColor3fv(color);
- ::glPushMatrix();
- ::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2));
+ glsafe(::glColor3fv(color));
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(m_grabbers[axis].center(0), m_grabbers[axis].center(1), m_grabbers[axis].center(2)));
if (axis == X)
- ::glRotated(90.0, 0.0, 1.0, 0.0);
+ glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
else if (axis == Y)
- ::glRotated(-90.0, 1.0, 0.0, 0.0);
+ glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
- ::glTranslated(0.0, 0.0, 2.0 * size);
+ glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
::gluQuadricOrientation(m_quadric, GLU_OUTSIDE);
::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1);
::gluQuadricOrientation(m_quadric, GLU_INSIDE);
::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
if (!picking)
- ::glDisable(GL_LIGHTING);
+ glsafe(::glDisable(GL_LIGHTING));
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
index e05ad00fe0..ff9cf380e2 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
@@ -155,13 +155,13 @@ void GLGizmoRotate::on_render(const Selection& selection) const
m_snap_fine_out_radius = m_radius * (1.0f + ScaleLongTooth);
}
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_DEPTH_TEST));
- ::glPushMatrix();
+ glsafe(::glPushMatrix());
transform_to_local(selection);
- ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
- ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
+ glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
+ glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color));
render_circle();
@@ -172,7 +172,7 @@ void GLGizmoRotate::on_render(const Selection& selection) const
render_reference_radius();
}
- ::glColor3fv(m_highlight_color);
+ glsafe(::glColor3fv(m_highlight_color));
if (m_hover_id != -1)
render_angle();
@@ -180,14 +180,14 @@ void GLGizmoRotate::on_render(const Selection& selection) const
render_grabber(box);
render_grabber_extension(box, false);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
void GLGizmoRotate::on_render_for_picking(const Selection& selection) const
{
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
- ::glPushMatrix();
+ glsafe(::glPushMatrix());
transform_to_local(selection);
@@ -195,7 +195,7 @@ void GLGizmoRotate::on_render_for_picking(const Selection& selection) const
render_grabbers_for_picking(box);
render_grabber_extension(box, true);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
void GLGizmoRotate::render_circle() const
@@ -209,7 +209,7 @@ void GLGizmoRotate::render_circle() const
float z = 0.0f;
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
- ::glEnd();
+ glsafe(::glEnd());
}
void GLGizmoRotate::render_scale() const
@@ -232,7 +232,7 @@ void GLGizmoRotate::render_scale() const
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
- ::glEnd();
+ glsafe(::glEnd());
}
void GLGizmoRotate::render_snap_radii() const
@@ -257,7 +257,7 @@ void GLGizmoRotate::render_snap_radii() const
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
- ::glEnd();
+ glsafe(::glEnd());
}
void GLGizmoRotate::render_reference_radius() const
@@ -265,7 +265,7 @@ void GLGizmoRotate::render_reference_radius() const
::glBegin(GL_LINES);
::glVertex3f(0.0f, 0.0f, 0.0f);
::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f);
- ::glEnd();
+ glsafe(::glEnd());
}
void GLGizmoRotate::render_angle() const
@@ -282,7 +282,7 @@ void GLGizmoRotate::render_angle() const
float z = 0.0f;
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
- ::glEnd();
+ glsafe(::glEnd());
}
void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const
@@ -291,12 +291,12 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
m_grabbers[0].angles(2) = m_angle;
- ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
+ glsafe(::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color));
::glBegin(GL_LINES);
::glVertex3f(0.0f, 0.0f, 0.0f);
::glVertex3dv(m_grabbers[0].center.data());
- ::glEnd();
+ glsafe(::glEnd());
::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float));
render_grabbers(box);
@@ -320,56 +320,56 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
}
if (!picking)
- ::glEnable(GL_LIGHTING);
+ glsafe(::glEnable(GL_LIGHTING));
- ::glColor3fv(color);
- ::glPushMatrix();
- ::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2));
- ::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0);
- ::glRotated(90.0, 1.0, 0.0, 0.0);
- ::glTranslated(0.0, 0.0, 2.0 * size);
+ glsafe(::glColor3fv(color));
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2)));
+ glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0));
+ glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
+ glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
::gluQuadricOrientation(m_quadric, GLU_OUTSIDE);
::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1);
::gluQuadricOrientation(m_quadric, GLU_INSIDE);
::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1);
- ::glPopMatrix();
- ::glPushMatrix();
- ::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2));
- ::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0);
- ::glRotated(-90.0, 1.0, 0.0, 0.0);
- ::glTranslated(0.0, 0.0, 2.0 * size);
+ glsafe(::glPopMatrix());
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(m_grabbers[0].center(0), m_grabbers[0].center(1), m_grabbers[0].center(2)));
+ glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0));
+ glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
+ glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
::gluQuadricOrientation(m_quadric, GLU_OUTSIDE);
::gluCylinder(m_quadric, 0.75 * size, 0.0, 3.0 * size, 36, 1);
::gluQuadricOrientation(m_quadric, GLU_INSIDE);
::gluDisk(m_quadric, 0.0, 0.75 * size, 36, 1);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
if (!picking)
- ::glDisable(GL_LIGHTING);
+ glsafe(::glDisable(GL_LIGHTING));
}
void GLGizmoRotate::transform_to_local(const Selection& selection) const
{
- ::glTranslated(m_center(0), m_center(1), m_center(2));
+ glsafe(::glTranslated(m_center(0), m_center(1), m_center(2)));
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
{
Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true);
- ::glMultMatrixd(orient_matrix.data());
+ glsafe(::glMultMatrixd(orient_matrix.data()));
}
switch (m_axis)
{
case X:
{
- ::glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
- ::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f);
+ glsafe(::glRotatef(90.0f, 0.0f, 1.0f, 0.0f));
+ glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f));
break;
}
case Y:
{
- ::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f);
- ::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
+ glsafe(::glRotatef(-90.0f, 0.0f, 0.0f, 1.0f));
+ glsafe(::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f));
break;
}
default:
@@ -472,7 +472,7 @@ void GLGizmoRotate3D::on_stop_dragging()
void GLGizmoRotate3D::on_render(const Selection& selection) const
{
- ::glClear(GL_DEPTH_BUFFER_BIT);
+ glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
if ((m_hover_id == -1) || (m_hover_id == 0))
m_gizmos[X].render(selection);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
index e9f7e2ae2d..a4f3969341 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
@@ -108,8 +108,8 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
((m_hover_id == 6) || (m_hover_id == 7) || (m_hover_id == 8) || (m_hover_id == 9)))
set_tooltip("X/Y/Z");
- ::glClear(GL_DEPTH_BUFFER_BIT);
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
+ glsafe(::glEnable(GL_DEPTH_TEST));
BoundingBoxf3 box;
Transform3d transform = Transform3d::Identity();
@@ -187,7 +187,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
m_grabbers[i].angles = angles;
}
- ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
+ glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
const BoundingBoxf3& selection_box = selection.get_bounding_box();
@@ -198,20 +198,20 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
// draw connections
if (m_grabbers[0].enabled && m_grabbers[1].enabled)
{
- ::glColor3fv(m_grabbers[0].color);
+ glsafe(::glColor3fv(m_grabbers[0].color));
render_grabbers_connection(0, 1);
}
if (m_grabbers[2].enabled && m_grabbers[3].enabled)
{
- ::glColor3fv(m_grabbers[2].color);
+ glsafe(::glColor3fv(m_grabbers[2].color));
render_grabbers_connection(2, 3);
}
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
{
- ::glColor3fv(m_grabbers[4].color);
+ glsafe(::glColor3fv(m_grabbers[4].color));
render_grabbers_connection(4, 5);
}
- ::glColor3fv(m_base_color);
+ glsafe(::glColor3fv(m_base_color));
render_grabbers_connection(6, 7);
render_grabbers_connection(7, 8);
render_grabbers_connection(8, 9);
@@ -222,7 +222,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
else if ((m_hover_id == 0) || (m_hover_id == 1))
{
// draw connection
- ::glColor3fv(m_grabbers[0].color);
+ glsafe(::glColor3fv(m_grabbers[0].color));
render_grabbers_connection(0, 1);
// draw grabbers
m_grabbers[0].render(true, grabber_mean_size);
@@ -231,7 +231,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
else if ((m_hover_id == 2) || (m_hover_id == 3))
{
// draw connection
- ::glColor3fv(m_grabbers[2].color);
+ glsafe(::glColor3fv(m_grabbers[2].color));
render_grabbers_connection(2, 3);
// draw grabbers
m_grabbers[2].render(true, grabber_mean_size);
@@ -240,7 +240,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
else if ((m_hover_id == 4) || (m_hover_id == 5))
{
// draw connection
- ::glColor3fv(m_grabbers[4].color);
+ glsafe(::glColor3fv(m_grabbers[4].color));
render_grabbers_connection(4, 5);
// draw grabbers
m_grabbers[4].render(true, grabber_mean_size);
@@ -249,7 +249,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
else if (m_hover_id >= 6)
{
// draw connection
- ::glColor3fv(m_drag_color);
+ glsafe(::glColor3fv(m_drag_color));
render_grabbers_connection(6, 7);
render_grabbers_connection(7, 8);
render_grabbers_connection(8, 9);
@@ -264,7 +264,7 @@ void GLGizmoScale3D::on_render(const Selection& selection) const
void GLGizmoScale3D::on_render_for_picking(const Selection& selection) const
{
- ::glDisable(GL_DEPTH_TEST);
+ glsafe(::glDisable(GL_DEPTH_TEST));
render_grabbers_for_picking(selection.get_bounding_box());
}
@@ -291,7 +291,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
::glBegin(GL_LINES);
::glVertex3dv(m_grabbers[id_1].center.data());
::glVertex3dv(m_grabbers[id_2].center.data());
- ::glEnd();
+ glsafe(::glEnd());
}
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 82b08a5e5a..43704a165d 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -1,5 +1,6 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoSlaSupports.hpp"
+#include "slic3r/GUI/GLCanvas3D.hpp"
#include
@@ -89,8 +90,8 @@ void GLGizmoSlaSupports::on_render(const Selection& selection) const
return;
}
- ::glEnable(GL_BLEND);
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_BLEND));
+ glsafe(::glEnable(GL_DEPTH_TEST));
// we'll recover current look direction from the modelview matrix (in world coords):
Eigen::Matrix modelview_matrix;
@@ -104,7 +105,7 @@ void GLGizmoSlaSupports::on_render(const Selection& selection) const
render_selection_rectangle();
render_clipping_plane(selection, direction_to_camera);
- ::glDisable(GL_BLEND);
+ glsafe(::glDisable(GL_BLEND));
}
@@ -160,44 +161,44 @@ void GLGizmoSlaSupports::render_selection_rectangle() const
if (!m_selection_rectangle_active)
return;
- ::glLineWidth(1.5f);
+ glsafe(::glLineWidth(1.5f));
float render_color[3] = {1.f, 0.f, 0.f};
- ::glColor3fv(render_color);
+ glsafe(::glColor3fv(render_color));
- ::glPushAttrib(GL_TRANSFORM_BIT); // remember current MatrixMode
+ glsafe(::glPushAttrib(GL_TRANSFORM_BIT)); // remember current MatrixMode
- ::glMatrixMode(GL_MODELVIEW); // cache modelview matrix and set to identity
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glMatrixMode(GL_MODELVIEW)); // cache modelview matrix and set to identity
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
- ::glMatrixMode(GL_PROJECTION); // cache projection matrix and set to identity
- ::glPushMatrix();
- ::glLoadIdentity();
+ glsafe(::glMatrixMode(GL_PROJECTION)); // cache projection matrix and set to identity
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
- ::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f); // set projection matrix so that world coords = window coords
+ glsafe(::glOrtho(0.f, m_canvas_width, m_canvas_height, 0.f, -1.f, 1.f)); // set projection matrix so that world coords = window coords
// render the selection rectangle (window coordinates):
- ::glPushAttrib(GL_ENABLE_BIT);
- ::glLineStipple(4, 0xAAAA);
- ::glEnable(GL_LINE_STIPPLE);
+ glsafe(::glPushAttrib(GL_ENABLE_BIT));
+ glsafe(::glLineStipple(4, 0xAAAA));
+ glsafe(::glEnable(GL_LINE_STIPPLE));
::glBegin(GL_LINE_LOOP);
::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f);
::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_start_corner(1), (GLfloat)0.5f);
::glVertex3f((GLfloat)m_selection_rectangle_end_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f);
::glVertex3f((GLfloat)m_selection_rectangle_start_corner(0), (GLfloat)m_selection_rectangle_end_corner(1), (GLfloat)0.5f);
- ::glEnd();
- ::glPopAttrib();
+ glsafe(::glEnd());
+ glsafe(::glPopAttrib());
- ::glPopMatrix(); // restore former projection matrix
- ::glMatrixMode(GL_MODELVIEW);
- ::glPopMatrix(); // restore former modelview matrix
- ::glPopAttrib(); // restore former MatrixMode
+ glsafe(::glPopMatrix()); // restore former projection matrix
+ glsafe(::glMatrixMode(GL_MODELVIEW));
+ glsafe(::glPopMatrix()); // restore former modelview matrix
+ glsafe(::glPopAttrib()); // restore former MatrixMode
}
void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const
{
- ::glEnable(GL_DEPTH_TEST);
+ glsafe(::glEnable(GL_DEPTH_TEST));
// we'll recover current look direction from the modelview matrix (in world coords):
Eigen::Matrix modelview_matrix;
@@ -210,15 +211,15 @@ void GLGizmoSlaSupports::on_render_for_picking(const Selection& selection) const
void GLGizmoSlaSupports::render_points(const Selection& selection, const Vec3d& direction_to_camera, bool picking) const
{
if (!picking)
- ::glEnable(GL_LIGHTING);
+ glsafe(::glEnable(GL_LIGHTING));
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
- ::glPushMatrix();
- ::glTranslated(0.0, 0.0, m_z_shift);
- ::glMultMatrixd(instance_matrix.data());
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(0.0, 0.0, m_z_shift));
+ glsafe(::glMultMatrixd(instance_matrix.data()));
float render_color[3];
for (int i = 0; i < (int)m_editing_mode_cache.size(); ++i)
@@ -253,14 +254,14 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, const Vec3d&
for (unsigned char i=0; i<3; ++i) render_color[i] = 0.5f;
}
}
- ::glColor3fv(render_color);
+ glsafe(::glColor3fv(render_color));
float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f};
- ::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive);
+ glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive));
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
- ::glPushMatrix();
- ::glTranslated(support_point.pos(0), support_point.pos(1), support_point.pos(2));
- ::glMultMatrixd(instance_scaling_matrix_inverse.data());
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslated(support_point.pos(0), support_point.pos(1), support_point.pos(2)));
+ glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
// Matrices set, we can render the point mark now.
// If in editing mode, we'll also render a cone pointing to the sphere.
@@ -271,31 +272,31 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, const Vec3d&
Eigen::Quaterniond q;
q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_mode_cache[i].normal.cast());
Eigen::AngleAxisd aa(q);
- ::glRotated(aa.angle() * (180./M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2));
+ glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
const float cone_radius = 0.25f; // mm
const float cone_height = 0.75f;
- ::glPushMatrix();
- ::glTranslatef(0.f, 0.f, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale);
+ glsafe(::glPushMatrix());
+ glsafe(::glTranslatef(0.f, 0.f, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale));
::gluCylinder(m_quadric, 0.f, cone_radius, cone_height, 24, 1);
- ::glTranslatef(0.f, 0.f, cone_height);
+ glsafe(::glTranslatef(0.f, 0.f, cone_height));
::gluDisk(m_quadric, 0.0, cone_radius, 24, 1);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
::gluSphere(m_quadric, m_editing_mode_cache[i].support_point.head_front_radius * RenderPointScale, 24, 12);
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
{
// Reset emissive component to zero (the default value)
float render_color_emissive[4] = { 0.f, 0.f, 0.f, 1.f };
- ::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive);
+ glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive));
}
if (!picking)
- ::glDisable(GL_LIGHTING);
+ glsafe(::glDisable(GL_LIGHTING));
- ::glPopMatrix();
+ glsafe(::glPopMatrix());
}
@@ -354,17 +355,15 @@ std::pair GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
if (m_V.size() == 0)
update_mesh();
- Eigen::Matrix viewport;
- ::glGetIntegerv(GL_VIEWPORT, viewport.data());
- Eigen::Matrix modelview_matrix;
- ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
- Eigen::Matrix projection_matrix;
- ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data());
+ const Camera& camera = m_parent.get_camera();
+ const std::array& viewport = camera.get_viewport();
+ const Transform3d& modelview_matrix = camera.get_view_matrix();
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
Vec3d point1;
Vec3d point2;
- ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
- ::gluUnProject(mouse_pos(0), viewport(3)-mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
+ ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 0.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point1(0), &point1(1), &point1(2));
+ ::gluUnProject(mouse_pos(0), viewport[3] - mouse_pos(1), 1.f, modelview_matrix.data(), projection_matrix.data(), viewport.data(), &point2(0), &point2(1), &point2(2));
std::vector hits;
@@ -472,12 +471,10 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
// left up with selection rectangle - select points inside the rectangle:
if ((action == SLAGizmoEventType::LeftUp || action == SLAGizmoEventType::ShiftUp) && m_selection_rectangle_active) {
const Transform3d& instance_matrix = m_model_object->instances[m_active_instance]->get_transformation().get_matrix();
- GLint viewport[4];
- ::glGetIntegerv(GL_VIEWPORT, viewport);
- GLdouble modelview_matrix[16];
- ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix);
- GLdouble projection_matrix[16];
- ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix);
+ const Camera& camera = m_parent.get_camera();
+ const std::array& viewport = camera.get_viewport();
+ const Transform3d& modelview_matrix = camera.get_view_matrix();
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
const Selection& selection = m_parent.get_selection();
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
@@ -488,7 +485,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
const Transform3d& instance_matrix_no_translation_no_scaling = volume->get_instance_transformation().get_matrix(true,false,true);
// we'll recover current look direction from the modelview matrix (in world coords)...
- Vec3f direction_to_camera(modelview_matrix[2], modelview_matrix[6], modelview_matrix[10]);
+ Vec3f direction_to_camera = camera.get_dir_forward().cast();
// ...and transform it to model coords.
Vec3f direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse().cast() * direction_to_camera).normalized().eval();
Vec3f scaling = volume->get_instance_scaling_factor().cast();
@@ -500,8 +497,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
Vec3f pos = instance_matrix.cast() * support_point.pos;
pos(2) += m_z_shift;
GLdouble out_x, out_y, out_z;
- ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z);
- out_y = m_canvas_height - out_y;
+ ::gluProject((GLdouble)pos(0), (GLdouble)pos(1), (GLdouble)pos(2), (GLdouble*)modelview_matrix.data(), (GLdouble*)projection_matrix.data(), (GLint*)viewport.data(), &out_x, &out_y, &out_z);
+ out_y = m_canvas_height - out_y;
if (rectangle.contains(Point(out_x, out_y)) && !is_point_clipped(support_point.pos.cast(), direction_to_camera.cast())) {
bool is_obscured = false;
@@ -692,10 +689,10 @@ void GLGizmoSlaSupports::update_cache_entry_normal(unsigned int i) const
-GLCanvas3D::ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
+ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
{
if (!m_model_object)
- return GLCanvas3D::ClippingPlane::ClipsNothing();
+ return ClippingPlane::ClipsNothing();
Eigen::Matrix modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
@@ -704,7 +701,7 @@ GLCanvas3D::ClippingPlane GLGizmoSlaSupports::get_sla_clipping_plane() const
Vec3d direction_to_camera(modelview_matrix.data()[2], modelview_matrix.data()[6], modelview_matrix.data()[10]);
float dist = direction_to_camera.dot(m_model_object->instances[m_active_instance]->get_offset() + Vec3d(0., 0., m_z_shift));
- return GLCanvas3D::ClippingPlane(-direction_to_camera.normalized(),(dist - (-m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_active_instance_bb_radius));
+ return ClippingPlane(-direction_to_camera.normalized(),(dist - (-m_active_instance_bb_radius) - m_clipping_plane_distance * 2*m_active_instance_bb_radius));
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
index d6df55f934..73d407f561 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp
@@ -2,6 +2,7 @@
#define slic3r_GLGizmoSlaSupports_hpp_
#include "GLGizmoBase.hpp"
+#include "GLGizmos.hpp"
// There is an L function in igl that would be overridden by our localization macro - let's undefine it...
#undef L
@@ -16,6 +17,9 @@ namespace Slic3r {
namespace GUI {
+class ClippingPlane;
+
+
class GLGizmoSlaSupports : public GLGizmoBase
{
private:
@@ -55,7 +59,7 @@ public:
void set_sla_support_data(ModelObject* model_object, const Selection& selection);
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down);
void delete_selected_points(bool force = false);
- GLCanvas3D::ClippingPlane get_sla_clipping_plane() const;
+ ClippingPlane get_sla_clipping_plane() const;
private:
bool on_init();
diff --git a/src/slic3r/GUI/Gizmos/GLGizmos.hpp b/src/slic3r/GUI/Gizmos/GLGizmos.hpp
index 8c5e25669d..c45b7648db 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmos.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmos.hpp
@@ -1,6 +1,21 @@
#ifndef slic3r_GLGizmos_hpp_
#define slic3r_GLGizmos_hpp_
+// this describes events being passed from GLCanvas3D to SlaSupport gizmo
+enum class SLAGizmoEventType {
+ LeftDown = 1,
+ LeftUp,
+ RightDown,
+ Dragging,
+ Delete,
+ SelectAll,
+ ShiftUp,
+ ApplyChanges,
+ DiscardChanges,
+ AutomaticGeneration,
+ ManualEditing
+};
+
#include "slic3r/GUI/Gizmos/GLGizmoMove.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoScale.hpp"
#include "slic3r/GUI/Gizmos/GLGizmoRotate.hpp"
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
new file mode 100644
index 0000000000..c0da0e1e99
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -0,0 +1,1228 @@
+#include "libslic3r/libslic3r.h"
+#include "GLGizmosManager.hpp"
+#include "slic3r/GUI/GLCanvas3D.hpp"
+#include "slic3r/GUI/3DScene.hpp"
+#include "slic3r/GUI/GUI_App.hpp"
+#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
+
+#include
+#include
+
+namespace Slic3r {
+namespace GUI {
+
+#if ENABLE_SVG_ICONS
+ const float GLGizmosManager::Default_Icons_Size = 64;
+#endif // ENABLE_SVG_ICONS
+
+GLGizmosManager::GLGizmosManager()
+ : m_enabled(false)
+#if ENABLE_SVG_ICONS
+ , m_icons_texture_dirty(true)
+#endif // ENABLE_SVG_ICONS
+ , m_current(Undefined)
+#if ENABLE_SVG_ICONS
+ , m_overlay_icons_size(Default_Icons_Size)
+ , m_overlay_scale(1.0f)
+ , m_overlay_border(5.0f)
+ , m_overlay_gap_y(5.0f)
+ , m_tooltip("")
+{
+}
+#else
+{
+ set_overlay_scale(1.0);
+}
+#endif // ENABLE_SVG_ICONS
+
+GLGizmosManager::~GLGizmosManager()
+{
+ reset();
+}
+
+bool GLGizmosManager::init(GLCanvas3D& parent)
+{
+#if !ENABLE_SVG_ICONS
+ m_icons_texture.metadata.filename = "gizmos.png";
+ m_icons_texture.metadata.icon_size = 64;
+
+ if (!m_icons_texture.metadata.filename.empty())
+ {
+ if (!m_icons_texture.texture.load_from_file(resources_dir() + "/icons/" + m_icons_texture.metadata.filename, false))
+ {
+ reset();
+ return false;
+ }
+ }
+#endif // !ENABLE_SVG_ICONS
+
+ m_background_texture.metadata.filename = "toolbar_background.png";
+ m_background_texture.metadata.left = 16;
+ m_background_texture.metadata.top = 16;
+ m_background_texture.metadata.right = 16;
+ m_background_texture.metadata.bottom = 16;
+
+ if (!m_background_texture.metadata.filename.empty())
+ {
+ if (!m_background_texture.texture.load_from_file(resources_dir() + "/icons/" + m_background_texture.metadata.filename, false))
+ {
+ reset();
+ return false;
+ }
+ }
+
+#if ENABLE_SVG_ICONS
+ GLGizmoBase* gizmo = new GLGizmoMove3D(parent, "move.svg", 0);
+#else
+ GLGizmoBase* gizmo = new GLGizmoMove3D(parent, 0);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init())
+ return false;
+
+ m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
+
+#if ENABLE_SVG_ICONS
+ gizmo = new GLGizmoScale3D(parent, "scale.svg", 1);
+#else
+ gizmo = new GLGizmoScale3D(parent, 1);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init())
+ return false;
+
+ m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
+
+#if ENABLE_SVG_ICONS
+ gizmo = new GLGizmoRotate3D(parent, "rotate.svg", 2);
+#else
+ gizmo = new GLGizmoRotate3D(parent, 2);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ {
+ reset();
+ return false;
+ }
+
+ if (!gizmo->init())
+ {
+ reset();
+ return false;
+ }
+
+ m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
+
+#if ENABLE_SVG_ICONS
+ gizmo = new GLGizmoFlatten(parent, "place.svg", 3);
+#else
+ gizmo = new GLGizmoFlatten(parent, 3);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init()) {
+ reset();
+ return false;
+ }
+
+ m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo));
+
+#if ENABLE_SVG_ICONS
+ gizmo = new GLGizmoCut(parent, "cut.svg", 4);
+#else
+ gizmo = new GLGizmoCut(parent, 4);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init()) {
+ reset();
+ return false;
+ }
+
+ m_gizmos.insert(GizmosMap::value_type(Cut, gizmo));
+
+#if ENABLE_SVG_ICONS
+ gizmo = new GLGizmoSlaSupports(parent, "sla_supports.svg", 5);
+#else
+ gizmo = new GLGizmoSlaSupports(parent, 5);
+#endif // ENABLE_SVG_ICONS
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init()) {
+ reset();
+ return false;
+ }
+
+ m_gizmos.insert(GizmosMap::value_type(SlaSupports, gizmo));
+
+ return true;
+}
+
+#if ENABLE_SVG_ICONS
+void GLGizmosManager::set_overlay_icon_size(float size)
+{
+ if (m_overlay_icons_size != size)
+ {
+ m_overlay_icons_size = size;
+ m_icons_texture_dirty = true;
+ }
+}
+#endif // ENABLE_SVG_ICONS
+
+void GLGizmosManager::set_overlay_scale(float scale)
+{
+#if ENABLE_SVG_ICONS
+ if (m_overlay_scale != scale)
+ {
+ m_overlay_scale = scale;
+ m_icons_texture_dirty = true;
+ }
+#else
+ m_overlay_icons_scale = scale;
+ m_overlay_border = 5.0f * scale;
+ m_overlay_gap_y = 5.0f * scale;
+#endif // ENABLE_SVG_ICONS
+}
+
+void GLGizmosManager::refresh_on_off_state(const Selection& selection)
+{
+ GizmosMap::iterator it = m_gizmos.find(m_current);
+ if ((it != m_gizmos.end()) && (it->second != nullptr))
+ {
+ if (!it->second->is_activable(selection))
+ {
+ it->second->set_state(GLGizmoBase::Off);
+ m_current = Undefined;
+ }
+ }
+}
+
+void GLGizmosManager::reset_all_states()
+{
+ if (!m_enabled)
+ return;
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second != nullptr)
+ {
+ it->second->set_state(GLGizmoBase::Off);
+ it->second->set_hover_id(-1);
+ }
+ }
+
+ m_current = Undefined;
+}
+
+void GLGizmosManager::set_hover_id(int id)
+{
+ if (!m_enabled)
+ return;
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On))
+ it->second->set_hover_id(id);
+ }
+}
+
+void GLGizmosManager::enable_grabber(EType type, unsigned int id, bool enable)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(type);
+ if (it != m_gizmos.end())
+ {
+ if (enable)
+ it->second->enable_grabber(id);
+ else
+ it->second->disable_grabber(id);
+ }
+}
+
+void GLGizmosManager::update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos)
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = get_current();
+ if (curr != nullptr)
+ curr->update(GLGizmoBase::UpdateData(mouse_ray, mouse_pos, shift_down), selection);
+}
+
+void GLGizmosManager::update_data(GLCanvas3D& canvas)
+{
+ if (!m_enabled)
+ return;
+
+ const Selection& selection = canvas.get_selection();
+
+ bool enable_move_z = !selection.is_wipe_tower();
+ enable_grabber(Move, 2, enable_move_z);
+ bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
+ for (int i = 0; i < 6; ++i)
+ {
+ enable_grabber(Scale, i, enable_scale_xyz);
+ }
+
+ if (selection.is_single_full_instance())
+ {
+ // all volumes in the selection belongs to the same instance, any of them contains the needed data, so we take the first
+ const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
+ set_scale(volume->get_instance_scaling_factor());
+ set_rotation(Vec3d::Zero());
+ ModelObject* model_object = selection.get_model()->objects[selection.get_object_idx()];
+ set_flattening_data(model_object);
+ set_sla_support_data(model_object, selection);
+ }
+ else if (selection.is_single_volume() || selection.is_single_modifier())
+ {
+ const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
+ set_scale(volume->get_volume_scaling_factor());
+ set_rotation(Vec3d::Zero());
+ set_flattening_data(nullptr);
+ set_sla_support_data(nullptr, selection);
+ }
+ else
+ {
+ set_scale(Vec3d::Ones());
+ set_rotation(Vec3d::Zero());
+ set_flattening_data(selection.is_from_single_object() ? selection.get_model()->objects[selection.get_object_idx()] : nullptr);
+ set_sla_support_data(nullptr, selection);
+ }
+}
+
+bool GLGizmosManager::is_running() const
+{
+ if (!m_enabled)
+ return false;
+
+ GLGizmoBase* curr = get_current();
+ return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false;
+}
+
+bool GLGizmosManager::handle_shortcut(int key, const Selection& selection)
+{
+ if (!m_enabled || selection.is_empty())
+ return false;
+
+ EType old_current = m_current;
+ bool handled = false;
+ for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+ int it_key = it->second->get_shortcut_key();
+
+ if (it->second->is_activable(selection) && ((it_key == key - 64) || (it_key == key - 96)))
+ {
+ if ((it->second->get_state() == GLGizmoBase::On))
+ {
+ it->second->set_state(GLGizmoBase::Off);
+ m_current = Undefined;
+ handled = true;
+ }
+ else if ((it->second->get_state() == GLGizmoBase::Off))
+ {
+ it->second->set_state(GLGizmoBase::On);
+ m_current = it->first;
+ handled = true;
+ }
+ }
+ }
+
+ if (handled && (old_current != Undefined) && (old_current != m_current))
+ {
+ GizmosMap::const_iterator it = m_gizmos.find(old_current);
+ if (it != m_gizmos.end())
+ it->second->set_state(GLGizmoBase::Off);
+ }
+
+ return handled;
+}
+
+bool GLGizmosManager::is_dragging() const
+{
+ if (!m_enabled)
+ return false;
+
+ GLGizmoBase* curr = get_current();
+ return (curr != nullptr) ? curr->is_dragging() : false;
+}
+
+void GLGizmosManager::start_dragging(const Selection& selection)
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = get_current();
+ if (curr != nullptr)
+ curr->start_dragging(selection);
+}
+
+void GLGizmosManager::stop_dragging()
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = get_current();
+ if (curr != nullptr)
+ curr->stop_dragging();
+}
+
+Vec3d GLGizmosManager::get_displacement() const
+{
+ if (!m_enabled)
+ return Vec3d::Zero();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Move);
+ return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_displacement() : Vec3d::Zero();
+}
+
+Vec3d GLGizmosManager::get_scale() const
+{
+ if (!m_enabled)
+ return Vec3d::Ones();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Scale);
+ return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_scale() : Vec3d::Ones();
+}
+
+void GLGizmosManager::set_scale(const Vec3d& scale)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Scale);
+ if (it != m_gizmos.end())
+ reinterpret_cast(it->second)->set_scale(scale);
+}
+
+Vec3d GLGizmosManager::get_rotation() const
+{
+ if (!m_enabled)
+ return Vec3d::Zero();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Rotate);
+ return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_rotation() : Vec3d::Zero();
+}
+
+void GLGizmosManager::set_rotation(const Vec3d& rotation)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Rotate);
+ if (it != m_gizmos.end())
+ reinterpret_cast(it->second)->set_rotation(rotation);
+}
+
+Vec3d GLGizmosManager::get_flattening_normal() const
+{
+ if (!m_enabled)
+ return Vec3d::Zero();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Flatten);
+ return (it != m_gizmos.end()) ? reinterpret_cast(it->second)->get_flattening_normal() : Vec3d::Zero();
+}
+
+void GLGizmosManager::set_flattening_data(const ModelObject* model_object)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Flatten);
+ if (it != m_gizmos.end())
+ reinterpret_cast(it->second)->set_flattening_data(model_object);
+}
+
+void GLGizmosManager::set_sla_support_data(ModelObject* model_object, const Selection& selection)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
+ if (it != m_gizmos.end())
+ reinterpret_cast(it->second)->set_sla_support_data(model_object, selection);
+}
+
+// Returns true if the gizmo used the event to do something, false otherwise.
+bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down)
+{
+ if (!m_enabled)
+ return false;
+
+ GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
+ if (it != m_gizmos.end())
+ return reinterpret_cast(it->second)->gizmo_event(action, mouse_position, shift_down);
+
+ return false;
+}
+
+ClippingPlane GLGizmosManager::get_sla_clipping_plane() const
+{
+ if (!m_enabled || m_current != SlaSupports)
+ return ClippingPlane::ClipsNothing();
+
+ GizmosMap::const_iterator it = m_gizmos.find(SlaSupports);
+ if (it != m_gizmos.end())
+ return reinterpret_cast(it->second)->get_sla_clipping_plane();
+
+ return ClippingPlane::ClipsNothing();
+}
+
+
+void GLGizmosManager::render_current_gizmo(const Selection& selection) const
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = get_current();
+ if (curr != nullptr)
+ curr->render(selection);
+}
+
+void GLGizmosManager::render_current_gizmo_for_picking_pass(const Selection& selection) const
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = get_current();
+ if (curr != nullptr)
+ curr->render_for_picking(selection);
+}
+
+void GLGizmosManager::render_overlay(const GLCanvas3D& canvas, const Selection& selection) const
+{
+ if (!m_enabled)
+ return;
+
+#if ENABLE_SVG_ICONS
+ if (m_icons_texture_dirty)
+ generate_icons_texture();
+#endif // ENABLE_SVG_ICONS
+
+ glsafe(::glDisable(GL_DEPTH_TEST));
+
+ glsafe(::glPushMatrix());
+ glsafe(::glLoadIdentity());
+
+ do_render_overlay(canvas, selection);
+
+ glsafe(::glPopMatrix());
+}
+
+bool GLGizmosManager::on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas)
+{
+ Point pos(evt.GetX(), evt.GetY());
+ Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
+
+ Selection& selection = canvas.get_selection();
+ int selected_object_idx = selection.get_object_idx();
+ bool processed = false;
+
+ // mouse anywhere
+ if (!evt.Dragging() && !evt.Leaving() && !evt.Entering() && (m_mouse_capture.parent != nullptr))
+ {
+ if (m_mouse_capture.any() && (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()))
+ // prevents loosing selection into the scene if mouse down was done inside the toolbar and mouse up was down outside it
+ processed = true;
+
+ m_mouse_capture.reset();
+ }
+
+ // mouse anywhere
+ if (evt.Moving())
+ m_tooltip = update_hover_state(canvas, mouse_pos);
+ else if (evt.LeftUp())
+ m_mouse_capture.left = false;
+ else if (evt.MiddleUp())
+ m_mouse_capture.middle = false;
+ else if (evt.RightUp())
+ m_mouse_capture.right = false;
+ else if (evt.Dragging() && m_mouse_capture.any())
+ // if the button down was done on this toolbar, prevent from dragging into the scene
+ processed = true;
+
+ if (!overlay_contains_mouse(canvas, mouse_pos))
+ {
+ // mouse is outside the toolbar
+ m_tooltip = "";
+
+ if (evt.LeftDown())
+ {
+ if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::LeftDown, mouse_pos, evt.ShiftDown()))
+ // the gizmo got the event and took some action, there is no need to do anything more
+ processed = true;
+ else if (!selection.is_empty() && grabber_contains_mouse())
+ {
+ update_data(canvas);
+ selection.start_dragging();
+ start_dragging(selection);
+
+ if (m_current == Flatten)
+ {
+ // Rotate the object so the normal points downward:
+ selection.flattening_rotate(get_flattening_normal());
+ canvas.do_flatten();
+ wxGetApp().obj_manipul()->update_settings_value(selection);
+ }
+
+ canvas.set_as_dirty();
+ processed = true;
+ }
+ }
+ else if (evt.RightDown() && (selected_object_idx != -1) && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::RightDown))
+ // event was taken care of by the SlaSupports gizmo
+ processed = true;
+ else if (evt.Dragging() && (canvas.get_move_volume_id() != -1) && (m_current == SlaSupports))
+ // don't allow dragging objects with the Sla gizmo on
+ processed = true;
+ else if (evt.Dragging() && (m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Dragging, mouse_pos, evt.ShiftDown()))
+ {
+ // the gizmo got the event and took some action, no need to do anything more here
+ canvas.set_as_dirty();
+ processed = true;
+ }
+ else if (evt.Dragging() && is_dragging())
+ {
+ if (!canvas.get_wxglcanvas()->HasCapture())
+ canvas.get_wxglcanvas()->CaptureMouse();
+
+ canvas.set_mouse_as_dragging();
+ update(canvas.mouse_ray(pos), selection, evt.ShiftDown(), &pos);
+
+ switch (m_current)
+ {
+ case Move:
+ {
+ // Apply new temporary offset
+ selection.translate(get_displacement());
+ wxGetApp().obj_manipul()->update_settings_value(selection);
+ break;
+ }
+ case Scale:
+ {
+ // Apply new temporary scale factors
+ selection.scale(get_scale(), evt.AltDown());
+ wxGetApp().obj_manipul()->update_settings_value(selection);
+ break;
+ }
+ case Rotate:
+ {
+ // Apply new temporary rotations
+ TransformationType transformation_type(TransformationType::World_Relative_Joint);
+ if (evt.AltDown())
+ transformation_type.set_independent();
+ selection.rotate(get_rotation(), transformation_type);
+ wxGetApp().obj_manipul()->update_settings_value(selection);
+ break;
+ }
+ default:
+ break;
+ }
+
+ canvas.set_as_dirty();
+ processed = true;
+ }
+ else if (evt.LeftUp() && is_dragging())
+ {
+ switch (m_current)
+ {
+ case Move:
+ {
+ canvas.disable_regenerate_volumes();
+ canvas.do_move();
+ break;
+ }
+ case Scale:
+ {
+ canvas.do_scale();
+ break;
+ }
+ case Rotate:
+ {
+ canvas.do_rotate();
+ break;
+ }
+ default:
+ break;
+ }
+
+ stop_dragging();
+ update_data(canvas);
+
+ wxGetApp().obj_manipul()->update_settings_value(selection);
+ // Let the platter know that the dragging finished, so a delayed refresh
+ // of the scene with the background processing data should be performed.
+ canvas.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
+ // updates camera target constraints
+ canvas.refresh_camera_scene_box();
+
+ processed = true;
+ }
+ else if (evt.LeftUp() && (m_current == SlaSupports) && !canvas.is_mouse_dragging())
+ {
+ // in case SLA gizmo is selected, we just pass the LeftUp event and stop processing - neither
+ // object moving or selecting is suppressed in that case
+ gizmo_event(SLAGizmoEventType::LeftUp, mouse_pos, evt.ShiftDown());
+ processed = true;
+ }
+ else if (evt.LeftUp() && (m_current == Flatten) && ((canvas.get_hover_volume_id() != -1) || grabber_contains_mouse()))
+ {
+ // to avoid to loose the selection when user clicks an object while the Flatten gizmo is active
+ processed = true;
+ }
+ }
+ else
+ {
+ // mouse inside toolbar
+ if (evt.LeftDown() || evt.LeftDClick())
+ {
+ m_mouse_capture.left = true;
+ m_mouse_capture.parent = &canvas;
+ processed = true;
+ if (!selection.is_empty())
+ {
+ update_on_off_state(canvas, mouse_pos, selection);
+ update_data(canvas);
+ canvas.set_as_dirty();
+ }
+ }
+ else if (evt.MiddleDown())
+ {
+ m_mouse_capture.middle = true;
+ m_mouse_capture.parent = &canvas;
+ }
+ else if (evt.RightDown())
+ {
+ m_mouse_capture.right = true;
+ m_mouse_capture.parent = &canvas;
+ }
+ else if (evt.LeftUp())
+ processed = true;
+ }
+
+ return processed;
+}
+
+bool GLGizmosManager::on_char(wxKeyEvent& evt, GLCanvas3D& canvas)
+{
+ // see include/wx/defs.h enum wxKeyCode
+ int keyCode = evt.GetKeyCode();
+ int ctrlMask = wxMOD_CONTROL;
+
+ bool processed = false;
+
+ if ((evt.GetModifiers() & ctrlMask) != 0)
+ {
+ switch (keyCode)
+ {
+ case WXK_CONTROL_A:
+ {
+ // Sla gizmo selects all support points
+ if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::SelectAll))
+ processed = true;
+
+ break;
+ }
+ }
+ }
+ else if (!evt.HasModifiers())
+ {
+ switch (keyCode)
+ {
+ // key ESC
+ case WXK_ESCAPE:
+ {
+ if ((m_current != SlaSupports) || !gizmo_event(SLAGizmoEventType::DiscardChanges))
+ reset_all_states();
+
+ processed = true;
+ break;
+ }
+ case WXK_RETURN:
+ {
+ if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::ApplyChanges))
+ processed = true;
+
+ break;
+ }
+#ifdef __APPLE__
+ case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead.
+#else /* __APPLE__ */
+ case WXK_DELETE:
+#endif /* __APPLE__ */
+ {
+ if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::Delete))
+ processed = true;
+
+ break;
+ }
+ case 'A':
+ case 'a':
+ {
+ if (m_current == SlaSupports)
+ {
+ gizmo_event(SLAGizmoEventType::AutomaticGeneration);
+ // set as processed no matter what's returned by gizmo_event() to avoid the calling canvas to process 'A' as arrange
+ processed = true;
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if ((m_current == SlaSupports) && gizmo_event(SLAGizmoEventType::ManualEditing))
+ processed = true;
+
+ break;
+ }
+ }
+ }
+
+ if (!processed)
+ {
+ if (handle_shortcut(keyCode, canvas.get_selection()))
+ {
+ update_data(canvas);
+ processed = true;
+ }
+ }
+
+ if (processed)
+ canvas.set_as_dirty();
+
+ return processed;
+}
+
+bool GLGizmosManager::on_key(wxKeyEvent& evt, GLCanvas3D& canvas)
+{
+ const int keyCode = evt.GetKeyCode();
+ bool processed = false;
+
+ if (evt.GetEventType() == wxEVT_KEY_UP)
+ {
+ if ((m_current == SlaSupports) && (keyCode == WXK_SHIFT) && gizmo_event(SLAGizmoEventType::ShiftUp))
+ // shift has been just released - SLA gizmo might want to close rectangular selection.
+ processed = true;
+ }
+
+ if (processed)
+ canvas.set_as_dirty();
+
+ return processed;
+}
+
+void GLGizmosManager::reset()
+{
+ for (GizmosMap::value_type& gizmo : m_gizmos)
+ {
+ delete gizmo.second;
+ gizmo.second = nullptr;
+ }
+
+ m_gizmos.clear();
+}
+
+void GLGizmosManager::do_render_overlay(const GLCanvas3D& canvas, const Selection& selection) const
+{
+ if (m_gizmos.empty())
+ return;
+
+ float cnv_w = (float)canvas.get_canvas_size().get_width();
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float zoom = canvas.get_camera().zoom;
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ float height = get_total_overlay_height();
+ float width = get_total_overlay_width();
+#if ENABLE_SVG_ICONS
+ float scaled_border = m_overlay_border * m_overlay_scale * inv_zoom;
+#else
+ float scaled_border = m_overlay_border * inv_zoom;
+#endif // ENABLE_SVG_ICONS
+
+ float top_x = (-0.5f * cnv_w) * inv_zoom;
+ float top_y = (0.5f * height) * inv_zoom;
+
+ float left = top_x;
+ float top = top_y;
+ float right = left + width * inv_zoom;
+ float bottom = top - height * inv_zoom;
+
+ // renders background
+ unsigned int bg_tex_id = m_background_texture.texture.get_id();
+ float bg_tex_width = (float)m_background_texture.texture.get_width();
+ float bg_tex_height = (float)m_background_texture.texture.get_height();
+ if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0))
+ {
+ float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f;
+ float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f;
+
+ float bg_uv_left = 0.0f;
+ float bg_uv_right = 1.0f;
+ float bg_uv_top = 1.0f;
+ float bg_uv_bottom = 0.0f;
+
+ float bg_left = left;
+ float bg_right = right;
+ float bg_top = top;
+ float bg_bottom = bottom;
+ float bg_width = right - left;
+ float bg_height = top - bottom;
+ float bg_min_size = std::min(bg_width, bg_height);
+
+ float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width;
+ float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width;
+ float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height;
+ float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height;
+
+ float bg_i_left = bg_left + scaled_border;
+ float bg_i_right = bg_right - scaled_border;
+ float bg_i_top = bg_top - scaled_border;
+ float bg_i_bottom = bg_bottom + scaled_border;
+
+ bg_uv_left = bg_uv_i_left;
+ bg_i_left = bg_left;
+
+ if ((m_overlay_border > 0) && (bg_uv_top != bg_uv_i_top))
+ {
+ if (bg_uv_left != bg_uv_i_left)
+ GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } });
+
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } });
+
+ if (bg_uv_right != bg_uv_i_right)
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } });
+ }
+
+ if ((m_overlay_border > 0) && (bg_uv_left != bg_uv_i_left))
+ GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } });
+
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } });
+
+ if ((m_overlay_border > 0) && (bg_uv_right != bg_uv_i_right))
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } });
+
+ if ((m_overlay_border > 0) && (bg_uv_bottom != bg_uv_i_bottom))
+ {
+ if (bg_uv_left != bg_uv_i_left)
+ GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } });
+
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } });
+
+ if (bg_uv_right != bg_uv_i_right)
+ GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } });
+ }
+ }
+
+#if ENABLE_SVG_ICONS
+ top_x += scaled_border;
+ top_y -= scaled_border;
+ float scaled_gap_y = m_overlay_gap_y * m_overlay_scale * inv_zoom;
+
+ float scaled_icons_size = m_overlay_icons_size * m_overlay_scale * inv_zoom;
+ float scaled_stride_y = scaled_icons_size + scaled_gap_y;
+ unsigned int icons_texture_id = m_icons_texture.get_id();
+ unsigned int tex_width = m_icons_texture.get_width();
+ unsigned int tex_height = m_icons_texture.get_height();
+ float inv_tex_width = (tex_width != 0) ? 1.0f / (float)tex_width : 0.0f;
+ float inv_tex_height = (tex_height != 0) ? 1.0f / (float)tex_height : 0.0f;
+#else
+ top_x += m_overlay_border * inv_zoom;
+ top_y -= m_overlay_border * inv_zoom;
+ float scaled_gap_y = m_overlay_gap_y * inv_zoom;
+
+ float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale * inv_zoom;
+ unsigned int icons_texture_id = m_icons_texture.texture.get_id();
+ unsigned int texture_size = m_icons_texture.texture.get_width();
+ float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
+#endif // ENABLE_SVG_ICONS
+
+#if ENABLE_SVG_ICONS
+ if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0))
+ return;
+#endif // ENABLE_SVG_ICONS
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+ unsigned int sprite_id = it->second->get_sprite_id();
+ GLGizmoBase::EState state = it->second->get_state();
+
+#if ENABLE_SVG_ICONS
+ float u_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_width;
+ float v_icon_size = m_overlay_icons_size * m_overlay_scale * inv_tex_height;
+ float v_top = sprite_id * v_icon_size;
+ float u_left = state * u_icon_size;
+ float v_bottom = v_top + v_icon_size;
+ float u_right = u_left + u_icon_size;
+#else
+ float uv_icon_size = (float)m_icons_texture.metadata.icon_size * inv_texture_size;
+ float v_top = sprite_id * uv_icon_size;
+ float u_left = state * uv_icon_size;
+ float v_bottom = v_top + uv_icon_size;
+ float u_right = u_left + uv_icon_size;
+#endif // ENABLE_SVG_ICONS
+
+ GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + scaled_icons_size, top_y - scaled_icons_size, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
+ if (it->second->get_state() == GLGizmoBase::On) {
+ float toolbar_top = (float)cnv_h - canvas.get_view_toolbar_height();
+#if ENABLE_SVG_ICONS
+ it->second->render_input_window(width, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection);
+#else
+ it->second->render_input_window(2.0f * m_overlay_border + icon_size * zoom, 0.5f * cnv_h - top_y * zoom, toolbar_top, selection);
+#endif // ENABLE_SVG_ICONS
+ }
+#if ENABLE_SVG_ICONS
+ top_y -= scaled_stride_y;
+#else
+ top_y -= (scaled_icons_size + scaled_gap_y);
+#endif // ENABLE_SVG_ICONS
+ }
+}
+
+float GLGizmosManager::get_total_overlay_height() const
+{
+#if ENABLE_SVG_ICONS
+ float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
+ float scaled_border = m_overlay_border * m_overlay_scale;
+ float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
+ float scaled_stride_y = scaled_icons_size + scaled_gap_y;
+ float height = 2.0f * scaled_border;
+#else
+ float height = 2.0f * m_overlay_border;
+
+ float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
+#endif // ENABLE_SVG_ICONS
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+#if ENABLE_SVG_ICONS
+ height += scaled_stride_y;
+#else
+ height += (scaled_icons_size + m_overlay_gap_y);
+#endif // ENABLE_SVG_ICONS
+ }
+
+#if ENABLE_SVG_ICONS
+ return height - scaled_gap_y;
+#else
+ return height - m_overlay_gap_y;
+#endif // ENABLE_SVG_ICONS
+}
+
+float GLGizmosManager::get_total_overlay_width() const
+{
+#if ENABLE_SVG_ICONS
+ return (2.0f * m_overlay_border + m_overlay_icons_size) * m_overlay_scale;
+#else
+ return (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale + 2.0f * m_overlay_border;
+#endif // ENABLE_SVG_ICONS
+}
+
+GLGizmoBase* GLGizmosManager::get_current() const
+{
+ GizmosMap::const_iterator it = m_gizmos.find(m_current);
+ return (it != m_gizmos.end()) ? it->second : nullptr;
+}
+
+#if ENABLE_SVG_ICONS
+bool GLGizmosManager::generate_icons_texture() const
+{
+ std::string path = resources_dir() + "/icons/";
+ std::vector filenames;
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second != nullptr)
+ {
+ const std::string& icon_filename = it->second->get_icon_filename();
+ if (!icon_filename.empty())
+ filenames.push_back(path + icon_filename);
+ }
+ }
+
+ std::vector> states;
+ states.push_back(std::make_pair(1, false));
+ states.push_back(std::make_pair(0, false));
+ states.push_back(std::make_pair(0, true));
+
+ bool res = m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, (unsigned int)(m_overlay_icons_size * m_overlay_scale));
+ if (res)
+ m_icons_texture_dirty = false;
+
+ return res;
+}
+#endif // ENABLE_SVG_ICONS
+
+void GLGizmosManager::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection)
+{
+ if (!m_enabled)
+ return;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = get_total_overlay_height();
+
+#if ENABLE_SVG_ICONS
+ float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
+ float scaled_border = m_overlay_border * m_overlay_scale;
+ float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
+ float scaled_stride_y = scaled_icons_size + scaled_gap_y;
+ float top_y = 0.5f * (cnv_h - height) + scaled_border;
+#else
+ float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
+ float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
+#endif // ENABLE_SVG_ICONS
+
+ for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+#if ENABLE_SVG_ICONS
+ bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
+#else
+ bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
+#endif // ENABLE_SVG_ICONS
+ if (it->second->is_activable(selection) && inside)
+ {
+ if ((it->second->get_state() == GLGizmoBase::On))
+ {
+ it->second->set_state(GLGizmoBase::Hover);
+ m_current = Undefined;
+ }
+ else if ((it->second->get_state() == GLGizmoBase::Hover))
+ {
+ it->second->set_state(GLGizmoBase::On);
+ m_current = it->first;
+ }
+ }
+ else
+ it->second->set_state(GLGizmoBase::Off);
+
+#if ENABLE_SVG_ICONS
+ top_y += scaled_stride_y;
+#else
+ top_y += (scaled_icons_size + m_overlay_gap_y);
+#endif // ENABLE_SVG_ICONS
+ }
+
+ GizmosMap::iterator it = m_gizmos.find(m_current);
+ if ((it != m_gizmos.end()) && (it->second != nullptr) && (it->second->get_state() != GLGizmoBase::On))
+ it->second->set_state(GLGizmoBase::On);
+}
+
+std::string GLGizmosManager::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos)
+{
+ std::string name = "";
+
+ if (!m_enabled)
+ return name;
+
+ const Selection& selection = canvas.get_selection();
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = get_total_overlay_height();
+#if ENABLE_SVG_ICONS
+ float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
+ float scaled_border = m_overlay_border * m_overlay_scale;
+ float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
+ float scaled_stride_y = scaled_icons_size + scaled_gap_y;
+ float top_y = 0.5f * (cnv_h - height) + scaled_border;
+#else
+ float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
+ float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
+#endif // ENABLE_SVG_ICONS
+
+ for (GizmosMap::iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+#if ENABLE_SVG_ICONS
+ bool inside = (scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
+#else
+ bool inside = (m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size);
+#endif // ENABLE_SVG_ICONS
+ if (inside)
+ name = it->second->get_name();
+
+ if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On))
+ it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
+
+#if ENABLE_SVG_ICONS
+ top_y += scaled_stride_y;
+#else
+ top_y += (scaled_icons_size + m_overlay_gap_y);
+#endif // ENABLE_SVG_ICONS
+ }
+
+ return name;
+}
+
+bool GLGizmosManager::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const
+{
+ if (!m_enabled)
+ return false;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = get_total_overlay_height();
+
+#if ENABLE_SVG_ICONS
+ float scaled_icons_size = m_overlay_icons_size * m_overlay_scale;
+ float scaled_border = m_overlay_border * m_overlay_scale;
+ float scaled_gap_y = m_overlay_gap_y * m_overlay_scale;
+ float scaled_stride_y = scaled_icons_size + scaled_gap_y;
+ float top_y = 0.5f * (cnv_h - height) + scaled_border;
+#else
+ float top_y = 0.5f * (cnv_h - height) + m_overlay_border;
+ float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * m_overlay_icons_scale;
+#endif // ENABLE_SVG_ICONS
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second == nullptr) || !it->second->is_selectable())
+ continue;
+
+#if ENABLE_SVG_ICONS
+ if ((scaled_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= scaled_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
+#else
+ if ((m_overlay_border <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= m_overlay_border + scaled_icons_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + scaled_icons_size))
+#endif // ENABLE_SVG_ICONS
+ return true;
+
+#if ENABLE_SVG_ICONS
+ top_y += scaled_stride_y;
+#else
+ top_y += (scaled_icons_size + m_overlay_gap_y);
+#endif // ENABLE_SVG_ICONS
+ }
+
+ return false;
+}
+
+bool GLGizmosManager::grabber_contains_mouse() const
+{
+ if (!m_enabled)
+ return false;
+
+ GLGizmoBase* curr = get_current();
+ return (curr != nullptr) ? (curr->get_hover_id() != -1) : false;
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
new file mode 100644
index 0000000000..7a6cc3c0a9
--- /dev/null
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -0,0 +1,186 @@
+#ifndef slic3r_GUI_GLGizmosManager_hpp_
+#define slic3r_GUI_GLGizmosManager_hpp_
+
+#include "slic3r/GUI/GLTexture.hpp"
+#include "slic3r/GUI/GLToolbar.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmos.hpp"
+
+#include