Merge branch 'master' into lm_sla_gizmo_clipping_plane

This commit is contained in:
Lukas Matena 2019-04-08 10:50:10 +02:00
commit eadf7daa37
31 changed files with 2444 additions and 2254 deletions

View file

@ -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).
<img width=256 src=https://cloud.githubusercontent.com/assets/31754/22719818/09998c92-ed6d-11e6-9fa0-09de638f3a36.png />
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?

View file

@ -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 ()

View file

@ -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.

View file

@ -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

View file

@ -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))

View file

@ -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<GLVolume*, double> GLVolumeWithZ;
typedef std::vector<GLVolumeWithZ> GLVolumesWithZList;
static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, std::function<bool(const GLVolume&)> filter_func)
static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> 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<bool(const GLVolume&)> filter_func) const
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> 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, &current_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<bool(const GLVolume&)> filter_func) const
void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> 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, &current_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));

View file

@ -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<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
void render_legacy(ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
void render_VBOs(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
void render_legacy(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
// Finalize the initialization of the geometry & indices,
// upload the geometry and indices to OpenGL VBO objects

View file

@ -1,9 +1,21 @@
#include "libslic3r/libslic3r.h"
#include "Camera.hpp"
#include "3DScene.hpp"
#include <GL/glew.h>
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

View file

@ -2,6 +2,7 @@
#define slic3r_Camera_hpp_
#include "libslic3r/BoundingBox.hpp"
#include <array>
namespace Slic3r {
namespace GUI {
@ -26,6 +27,10 @@ private:
Vec3d m_target;
float m_theta;
mutable std::array<int, 4> 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<int, 4>& 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

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,7 @@
#include "3DBed.hpp"
#include "Camera.hpp"
#include "Selection.hpp"
#include "Gizmos/GLGizmosManager.hpp"
#include <float.h>
@ -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<Vec2d>;
@ -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<EType, GLGizmoBase*> 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();

View file

@ -3,6 +3,7 @@
#include "GLShader.hpp"
#include "libslic3r/Utils.hpp"
#include "3DScene.hpp"
#include <boost/nowide/fstream.hpp>
#include <string>
@ -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, &params);
glsafe(::glGetShaderiv(this->fragment_program_id, GL_COMPILE_STATUS, &params));
if (params == GL_FALSE) {
// Compilation failed. Get the log.
glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, &params);
glsafe(::glGetShaderiv(this->fragment_program_id, GL_INFO_LOG_LENGTH, &params));
std::vector<char> msg(params);
glGetShaderInfoLog(this->fragment_program_id, params, &params, msg.data());
glsafe(::glGetShaderInfoLog(this->fragment_program_id, params, &params, 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, &params);
glsafe(::glGetShaderiv(this->vertex_program_id, GL_COMPILE_STATUS, &params));
if (params == GL_FALSE) {
// Compilation failed. Get the log.
glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, &params);
glsafe(::glGetShaderiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, &params));
std::vector<char> msg(params);
glGetShaderInfoLog(this->vertex_program_id, params, &params, msg.data());
glsafe(::glGetShaderInfoLog(this->vertex_program_id, params, &params, 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, &params);
glsafe(::glGetProgramiv(this->shader_program_id, GL_LINK_STATUS, &params));
if (params == GL_FALSE) {
// Linking failed. Get the log.
glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, &params);
glsafe(::glGetProgramiv(this->vertex_program_id, GL_INFO_LOG_LENGTH, &params));
std::vector<char> msg(params);
glGetProgramInfoLog(this->vertex_program_id, params, &params, msg.data());
glsafe(::glGetProgramInfoLog(this->vertex_program_id, params, &params, 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;

View file

@ -1,6 +1,8 @@
#include "libslic3r/libslic3r.h"
#include "GLTexture.hpp"
#include "3DScene.hpp"
#include <GL/glew.h>
#include <wx/image.h>
@ -173,15 +175,15 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
nsvgDeleteRasterizer(rast);
// sends data to gpu
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
::glGenTextures(1, &m_id);
::glBindTexture(GL_TEXTURE_2D, 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_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, 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_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
::glBindTexture(GL_TEXTURE_2D, 0);
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
m_source = filenames.front();
@ -214,7 +216,7 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
void GLTexture::reset()
{
if (m_id != 0)
::glDeleteTextures(1, &m_id);
glsafe(::glDeleteTextures(1, &m_id));
m_id = 0;
m_width = 0;
@ -229,25 +231,25 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo
void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const GLTexture::Quad_UVs& uvs)
{
::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));
::glEnable(GL_TEXTURE_2D);
::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glsafe(::glEnable(GL_TEXTURE_2D));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE));
::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id);
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
::glBegin(GL_QUADS);
::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
::glEnd();
glsafe(::glEnd());
::glBindTexture(GL_TEXTURE_2D, 0);
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
::glDisable(GL_TEXTURE_2D);
::glDisable(GL_BLEND);
glsafe(::glDisable(GL_TEXTURE_2D));
glsafe(::glDisable(GL_BLEND));
}
unsigned int GLTexture::generate_mipmaps(wxImage& image)
@ -282,7 +284,7 @@ unsigned int GLTexture::generate_mipmaps(wxImage& image)
data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255;
}
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
glsafe(::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
}
return (unsigned int)level;
@ -330,25 +332,25 @@ bool GLTexture::load_from_png(const std::string& filename, bool use_mipmaps)
}
// sends data to gpu
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
::glGenTextures(1, &m_id);
::glBindTexture(GL_TEXTURE_2D, 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());
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, 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()));
if (use_mipmaps)
{
// we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
unsigned int levels_count = generate_mipmaps(image);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels_count);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels_count));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
}
else
{
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
}
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
::glBindTexture(GL_TEXTURE_2D, 0);
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
m_source = filename;
@ -392,10 +394,10 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, uns
nsvgRasterize(rast, image, 0, 0, scale, data.data(), m_width, m_height, m_width * 4);
// sends data to gpu
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
::glGenTextures(1, &m_id);
::glBindTexture(GL_TEXTURE_2D, 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());
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glGenTextures(1, &m_id));
glsafe(::glBindTexture(GL_TEXTURE_2D, 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()));
if (use_mipmaps)
{
// we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
@ -411,20 +413,20 @@ bool GLTexture::load_from_svg(const std::string& filename, bool use_mipmaps, uns
scale /= 2.0f;
nsvgRasterize(rast, image, 0, 0, scale, data.data(), lod_w, lod_h, lod_w * 4);
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)lod_w, (GLsizei)lod_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
glsafe(::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)lod_w, (GLsizei)lod_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
}
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
}
else
{
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
}
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
::glBindTexture(GL_TEXTURE_2D, 0);
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
m_source = filename;

View file

@ -388,10 +388,10 @@ void GLToolbar::render(const GLCanvas3D& parent) const
generate_icons_texture();
#endif // ENABLE_SVG_ICONS
::glDisable(GL_DEPTH_TEST);
glsafe(::glDisable(GL_DEPTH_TEST));
::glPushMatrix();
::glLoadIdentity();
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
switch (m_layout.type)
{
@ -400,7 +400,7 @@ void GLToolbar::render(const GLCanvas3D& parent) const
case Layout::Vertical: { render_vertical(parent); break; }
}
::glPopMatrix();
glsafe(::glPopMatrix());
}
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
@ -444,11 +444,11 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
{
m_mouse_capture.left = true;
m_mouse_capture.parent = &parent;
processed = true;
if ((item_id != -2) && !m_items[item_id]->is_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;

View file

@ -7,6 +7,7 @@
#include "GLTexture.hpp"
#include "Event.hpp"
#include "libslic3r/Point.hpp"
class wxEvtHandler;

View file

@ -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();
}

View file

@ -1,4 +1,5 @@
#include "GLGizmoBase.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include <GL/glew.h>
@ -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

View file

@ -3,7 +3,6 @@
#include "libslic3r/Point.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/I18N.hpp"
#include "slic3r/GUI/Selection.hpp"

View file

@ -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 <GL/glew.h>
@ -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());
}

View file

@ -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<GLGizmoFlatten*>(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<GLGizmoFlatten*>(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)

View file

@ -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));
}

View file

@ -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);

View file

@ -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());
}
}

View file

@ -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 <GL/glew.h>
@ -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<double, 4, 4, Eigen::DontAlign> 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<double, 4, 4, Eigen::DontAlign> 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<double>());
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<Vec3f, Vec3f> GLGizmoSlaSupports::unproject_on_mesh(const Vec2d& mouse
if (m_V.size() == 0)
update_mesh();
Eigen::Matrix<GLint, 4, 1, Eigen::DontAlign> viewport;
::glGetIntegerv(GL_VIEWPORT, viewport.data());
Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> modelview_matrix;
::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
Eigen::Matrix<GLdouble, 4, 4, Eigen::DontAlign> projection_matrix;
::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix.data());
const Camera& camera = m_parent.get_camera();
const std::array<int, 4>& viewport = camera.get_viewport();
const Transform3d& modelview_matrix = camera.get_view_matrix();
const Transform3d& projection_matrix = camera.get_projection_matrix();
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<igl::Hit> 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<int, 4>& 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<float>();
// ...and transform it to model coords.
Vec3f direction_to_camera_mesh = (instance_matrix_no_translation_no_scaling.inverse().cast<float>() * direction_to_camera).normalized().eval();
Vec3f scaling = volume->get_instance_scaling_factor().cast<float>();
@ -500,8 +497,8 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
Vec3f pos = instance_matrix.cast<float>() * 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<double>(), direction_to_camera.cast<double>())) {
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<GLdouble, 4, 4, Eigen::DontAlign> 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));
}

View file

@ -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();

View file

@ -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"

File diff suppressed because it is too large Load diff

View file

@ -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 <map>
namespace Slic3r {
namespace GUI {
class Selection;
class GLGizmoBase;
class GLCanvas3D;
class ClippingPlane;
class Rect
{
float m_left;
float m_top;
float m_right;
float m_bottom;
public:
Rect() : m_left(0.0f) , m_top(0.0f) , m_right(0.0f) , m_bottom(0.0f) {}
Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {}
float get_left() const { return m_left; }
void set_left(float left) { m_left = left; }
float get_top() const { return m_top; }
void set_top(float top) { m_top = top; }
float get_right() const { return m_right; }
void set_right(float right) { m_right = right; }
float get_bottom() const { return m_bottom; }
void set_bottom(float bottom) { m_bottom = bottom; }
float get_width() const { return m_right - m_left; }
float get_height() const { return m_top - m_bottom; }
};
class GLGizmosManager
{
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<EType, GLGizmoBase*> 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;
struct MouseCapture
{
bool left;
bool middle;
bool right;
GLCanvas3D* parent;
MouseCapture() { reset(); }
bool any() const { return left || middle || right; }
void reset() { left = middle = right = false; parent = nullptr; }
};
MouseCapture m_mouse_capture;
std::string m_tooltip;
public:
GLGizmosManager();
~GLGizmosManager();
bool init(GLCanvas3D& parent);
bool is_enabled() const { return m_enabled; }
void set_enabled(bool enable) { m_enabled = enable; }
#if ENABLE_SVG_ICONS
void set_overlay_icon_size(float size);
#endif // ENABLE_SVG_ICONS
void set_overlay_scale(float scale);
void refresh_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);
void update(const Linef3& mouse_ray, const Selection& selection, bool shift_down, const Point* mouse_pos = nullptr);
void update_data(GLCanvas3D& canvas);
Rect get_reset_rect_viewport(const GLCanvas3D& canvas) const;
EType get_current_type() const { return m_current; }
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;
const std::string& get_tooltip() const { return m_tooltip; }
bool on_mouse(wxMouseEvent& evt, GLCanvas3D& canvas);
bool on_char(wxKeyEvent& evt, GLCanvas3D& canvas);
bool on_key(wxKeyEvent& evt, GLCanvas3D& canvas);
private:
void reset();
void do_render_overlay(const GLCanvas3D& canvas, 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
void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos, const Selection& selection);
std::string update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos);
bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const;
bool grabber_contains_mouse() const;
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GUI_GLGizmosManager_hpp_

View file

@ -19,6 +19,7 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "3DScene.hpp"
#include "GUI.hpp"
namespace Slic3r {
@ -359,19 +360,19 @@ void ImGuiWrapper::init_font()
// Upload texture to graphics system
GLint last_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGenTextures(1, &m_font_texture);
glBindTexture(GL_TEXTURE_2D, m_font_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
glsafe(::glGenTextures(1, &m_font_texture));
glsafe(::glBindTexture(GL_TEXTURE_2D, m_font_texture));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)m_font_texture;
// Restore state
glBindTexture(GL_TEXTURE_2D, last_texture);
glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
}
void ImGuiWrapper::init_input()
@ -466,39 +467,39 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GLint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
GLint last_polygon_mode[2]; glsafe(::glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode));
GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport));
GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box));
glsafe(::glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
glsafe(::glDisable(GL_CULL_FACE));
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glDisable(GL_LIGHTING));
glsafe(::glDisable(GL_COLOR_MATERIAL));
glsafe(::glEnable(GL_SCISSOR_TEST));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glEnableClientState(GL_COLOR_ARRAY));
glsafe(::glEnable(GL_TEXTURE_2D));
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
GLint texture_env_mode = GL_MODULATE;
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
glsafe(::glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f));
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// Render command lists
ImVec2 pos = draw_data->DisplayPos;
@ -507,9 +508,9 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
const ImDrawList* cmd_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col)));
glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))));
glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))));
glsafe(::glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
@ -525,11 +526,11 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{
// Apply scissor/clipping rectangle
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
glsafe(::glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)));
// Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId));
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer));
}
}
idx_buffer += pcmd->ElemCount;
@ -537,19 +538,19 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
}
// Restore modified state
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode));
glsafe(::glDisableClientState(GL_COLOR_ARRAY));
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture));
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glPopMatrix());
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glPopMatrix());
glsafe(::glPopAttrib());
glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]));
glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]));
glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]));
}
bool ImGuiWrapper::display_initialized() const
@ -563,7 +564,7 @@ void ImGuiWrapper::destroy_font()
if (m_font_texture != 0) {
ImGuiIO& io = ImGui::GetIO();
io.Fonts->TexID = 0;
glDeleteTextures(1, &m_font_texture);
glsafe(::glDeleteTextures(1, &m_font_texture));
m_font_texture = 0;
}
}

View file

@ -6,6 +6,7 @@
#include "GUI_ObjectManipulation.hpp"
#include "GUI_ObjectList.hpp"
#include "Gizmos/GLGizmoBase.hpp"
#include "slic3r/GUI/3DScene.hpp"
#include <GL/glew.h>
@ -75,7 +76,7 @@ Selection::~Selection()
void Selection::set_volumes(GLVolumePtrs* volumes)
{
m_volumes = volumes;
_update_valid();
update_valid();
}
bool Selection::init(bool useVBOs)
@ -95,7 +96,7 @@ bool Selection::init(bool useVBOs)
void Selection::set_model(Model* model)
{
m_model = model;
_update_valid();
update_valid();
}
void Selection::add(unsigned int volume_idx, bool as_single_selection)
@ -134,18 +135,18 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection)
case Volume:
{
if ((volume->volume_idx() >= 0) && (is_empty() || (volume->instance_idx() == get_instance_idx())))
_add_volume(volume_idx);
do_add_volume(volume_idx);
break;
}
case Instance:
{
_add_instance(volume->object_idx(), volume->instance_idx());
do_add_instance(volume->object_idx(), volume->instance_idx());
break;
}
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -160,17 +161,17 @@ void Selection::remove(unsigned int volume_idx)
{
case Volume:
{
_remove_volume(volume_idx);
do_remove_volume(volume_idx);
break;
}
case Instance:
{
_remove_instance(volume->object_idx(), volume->instance_idx());
do_remove_instance(volume->object_idx(), volume->instance_idx());
break;
}
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -185,9 +186,9 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection)
m_mode = Instance;
_add_object(object_idx);
do_add_object(object_idx);
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -196,9 +197,9 @@ void Selection::remove_object(unsigned int object_idx)
if (!m_valid)
return;
_remove_object(object_idx);
do_remove_object(object_idx);
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -213,9 +214,9 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx,
m_mode = Instance;
_add_instance(object_idx, instance_idx);
do_add_instance(object_idx, instance_idx);
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -224,9 +225,9 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i
if (!m_valid)
return;
_remove_instance(object_idx, instance_idx);
do_remove_instance(object_idx, instance_idx);
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -247,11 +248,11 @@ void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int
if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx))
{
if ((instance_idx != -1) && (v->instance_idx() == instance_idx))
_add_volume(i);
do_add_volume(i);
}
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -264,10 +265,10 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx))
_remove_volume(i);
do_remove_volume(i);
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -282,10 +283,10 @@ void Selection::add_all()
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
if (!(*m_volumes)[i]->is_wipe_tower)
_add_volume(i);
do_add_volume(i);
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -301,7 +302,7 @@ void Selection::clear()
m_list.clear();
_update_type();
update_type();
m_bounding_box_dirty = true;
// resets the cache in the sidebar
@ -341,11 +342,11 @@ void Selection::volumes_changed(const std::vector<size_t> &map_volume_old_to_new
const GLVolume* volume = (*m_volumes)[i];
for (const std::pair<int, int> &model_instance : model_instances)
if (volume->object_idx() == model_instance.first && volume->instance_idx() == model_instance.second)
this->_add_volume(i);
do_add_volume(i);
}
}
_update_type();
update_type();
m_bounding_box_dirty = true;
}
@ -426,7 +427,7 @@ const GLVolume* Selection::get_volume(unsigned int volume_idx) const
const BoundingBoxf3& Selection::get_bounding_box() const
{
if (m_bounding_box_dirty)
_calc_bounding_box();
calc_bounding_box();
return m_bounding_box;
}
@ -436,7 +437,7 @@ void Selection::start_dragging()
if (!m_valid)
return;
_set_caches();
set_caches();
}
void Selection::translate(const Vec3d& displacement, bool local)
@ -460,7 +461,7 @@ void Selection::translate(const Vec3d& displacement, bool local)
}
else if (m_mode == Instance)
{
if (_is_from_fully_selected_instance(i))
if (is_from_fully_selected_instance(i))
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
else
{
@ -473,9 +474,9 @@ void Selection::translate(const Vec3d& displacement, bool local)
#if !DISABLE_INSTANCES_SYNCH
if (translation_type == Instance)
_synchronize_unselected_instances(SYNC_ROTATION_NONE);
synchronize_unselected_instances(SYNC_ROTATION_NONE);
else if (translation_type == Volume)
_synchronize_unselected_volumes();
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true;
@ -604,9 +605,9 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
_synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL);
synchronize_unselected_instances((rot_axis_max == 2) ? SYNC_ROTATION_NONE : SYNC_ROTATION_GENERAL);
else if (m_mode == Volume)
_synchronize_unselected_volumes();
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true;
@ -647,7 +648,7 @@ void Selection::flattening_rotate(const Vec3d& normal)
// we want to synchronize z-rotation as well, otherwise the flattening behaves funny
// when applied on one of several identical instances
if (m_mode == Instance)
_synchronize_unselected_instances(SYNC_ROTATION_FULL);
synchronize_unselected_instances(SYNC_ROTATION_FULL);
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true;
@ -694,12 +695,12 @@ void Selection::scale(const Vec3d& scale, bool local)
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
_synchronize_unselected_instances(SYNC_ROTATION_NONE);
synchronize_unselected_instances(SYNC_ROTATION_NONE);
else if (m_mode == Volume)
_synchronize_unselected_volumes();
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
_ensure_on_bed();
ensure_on_bed();
m_bounding_box_dirty = true;
}
@ -721,9 +722,9 @@ void Selection::mirror(Axis axis)
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
_synchronize_unselected_instances(SYNC_ROTATION_NONE);
synchronize_unselected_instances(SYNC_ROTATION_NONE);
else if (m_mode == Volume)
_synchronize_unselected_volumes();
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
m_bounding_box_dirty = true;
@ -941,8 +942,8 @@ void Selection::render(float scale_factor) const
m_scale_factor = scale_factor;
// render cumulative bounding box of selected volumes
_render_selected_volumes();
_render_synchronized_volumes();
render_selected_volumes();
render_synchronized_volumes();
}
#if ENABLE_RENDER_SELECTION_CENTER
@ -953,17 +954,17 @@ void Selection::render_center() const
const Vec3d& center = get_bounding_box().center();
::glDisable(GL_DEPTH_TEST);
glsafe(::glDisable(GL_DEPTH_TEST)));
::glEnable(GL_LIGHTING);
glsafe(::glEnable(GL_LIGHTING));
::glColor3f(1.0f, 1.0f, 1.0f);
::glPushMatrix();
::glTranslated(center(0), center(1), center(2));
::gluSphere(m_quadric, 0.75, 32, 32);
::glPopMatrix();
glsafe(::glColor3f(1.0f, 1.0f, 1.0f));
glsafe(::glPushMatrix());
glsafe(::glTranslated(center(0), center(1), center(2)));
glsafe(::gluSphere(m_quadric, 0.75, 32, 32));
glsafe(::glPopMatrix());
::glDisable(GL_LIGHTING);
glsafe(::glDisable(GL_LIGHTING));
}
#endif // ENABLE_RENDER_SELECTION_CENTER
@ -972,18 +973,18 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const
if (sidebar_field.empty())
return;
::glClear(GL_DEPTH_BUFFER_BIT);
::glEnable(GL_DEPTH_TEST);
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
glsafe(::glEnable(GL_DEPTH_TEST));
::glEnable(GL_LIGHTING);
glsafe(::glEnable(GL_LIGHTING));
::glPushMatrix();
glsafe(::glPushMatrix());
const Vec3d& center = get_bounding_box().center();
if (is_single_full_instance())
{
::glTranslated(center(0), center(1), center(2));
glsafe(::glTranslated(center(0), center(1), center(2)));
if (!boost::starts_with(sidebar_field, "position"))
{
Transform3d orient_matrix = Transform3d::Identity();
@ -1003,40 +1004,40 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) const
}
}
::glMultMatrixd(orient_matrix.data());
glsafe(::glMultMatrixd(orient_matrix.data()));
}
}
else if (is_single_volume() || is_single_modifier())
{
::glTranslated(center(0), center(1), center(2));
glsafe(::glTranslated(center(0), center(1), center(2)));
Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
if (!boost::starts_with(sidebar_field, "position"))
orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_matrix(true, false, true, true);
::glMultMatrixd(orient_matrix.data());
glsafe(::glMultMatrixd(orient_matrix.data()));
}
else
{
::glTranslated(center(0), center(1), center(2));
glsafe(::glTranslated(center(0), center(1), center(2)));
if (requires_local_axes())
{
Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true);
::glMultMatrixd(orient_matrix.data());
glsafe(::glMultMatrixd(orient_matrix.data()));
}
}
if (boost::starts_with(sidebar_field, "position"))
_render_sidebar_position_hints(sidebar_field);
render_sidebar_position_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "rotation"))
_render_sidebar_rotation_hints(sidebar_field);
render_sidebar_rotation_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "scale"))
_render_sidebar_scale_hints(sidebar_field);
render_sidebar_scale_hints(sidebar_field);
else if (boost::starts_with(sidebar_field, "size"))
_render_sidebar_size_hints(sidebar_field);
render_sidebar_size_hints(sidebar_field);
::glPopMatrix();
glsafe(::glPopMatrix());
::glDisable(GL_LIGHTING);
glsafe(::glDisable(GL_LIGHTING));
}
bool Selection::requires_local_axes() const
@ -1044,12 +1045,12 @@ bool Selection::requires_local_axes() const
return (m_mode == Volume) && is_from_single_instance();
}
void Selection::_update_valid()
void Selection::update_valid()
{
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
}
void Selection::_update_type()
void Selection::update_type()
{
m_cache.content.clear();
m_type = Mixed;
@ -1150,9 +1151,9 @@ void Selection::_update_type()
m_type = MultipleVolume;
else if (modifiers_count == (unsigned int)m_list.size())
m_type = MultipleModifier;
}
requires_disable = true;
requires_disable = true;
}
}
else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size()))
{
@ -1273,7 +1274,7 @@ void Selection::_update_type()
#endif // ENABLE_SELECTION_DEBUG_OUTPUT
}
void Selection::_set_caches()
void Selection::set_caches()
{
m_cache.volumes_data.clear();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
@ -1284,33 +1285,33 @@ void Selection::_set_caches()
m_cache.dragging_center = get_bounding_box().center();
}
void Selection::_add_volume(unsigned int volume_idx)
void Selection::do_add_volume(unsigned int volume_idx)
{
m_list.insert(volume_idx);
(*m_volumes)[volume_idx]->selected = true;
}
void Selection::_add_instance(unsigned int object_idx, unsigned int instance_idx)
void Selection::do_add_instance(unsigned int object_idx, unsigned int instance_idx)
{
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
_add_volume(i);
do_add_volume(i);
}
}
void Selection::_add_object(unsigned int object_idx)
void Selection::do_add_object(unsigned int object_idx)
{
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx)
_add_volume(i);
do_add_volume(i);
}
}
void Selection::_remove_volume(unsigned int volume_idx)
void Selection::do_remove_volume(unsigned int volume_idx)
{
IndicesList::iterator v_it = m_list.find(volume_idx);
if (v_it == m_list.end())
@ -1321,27 +1322,27 @@ void Selection::_remove_volume(unsigned int volume_idx)
(*m_volumes)[volume_idx]->selected = false;
}
void Selection::_remove_instance(unsigned int object_idx, unsigned int instance_idx)
void Selection::do_remove_instance(unsigned int object_idx, unsigned int instance_idx)
{
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
_remove_volume(i);
do_remove_volume(i);
}
}
void Selection::_remove_object(unsigned int object_idx)
void Selection::do_remove_object(unsigned int object_idx)
{
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx)
_remove_volume(i);
do_remove_volume(i);
}
}
void Selection::_calc_bounding_box() const
void Selection::calc_bounding_box() const
{
m_bounding_box = BoundingBoxf3();
if (m_valid)
@ -1354,13 +1355,13 @@ void Selection::_calc_bounding_box() const
m_bounding_box_dirty = false;
}
void Selection::_render_selected_volumes() const
void Selection::render_selected_volumes() const
{
float color[3] = { 1.0f, 1.0f, 1.0f };
_render_bounding_box(get_bounding_box(), color);
render_bounding_box(get_bounding_box(), color);
}
void Selection::_render_synchronized_volumes() const
void Selection::render_synchronized_volumes() const
{
if (m_mode == Instance)
return;
@ -1382,12 +1383,12 @@ void Selection::_render_synchronized_volumes() const
if ((v->object_idx() != object_idx) || (v->volume_idx() != volume_idx))
continue;
_render_bounding_box(v->transformed_convex_hull_bounding_box(), color);
render_bounding_box(v->transformed_convex_hull_bounding_box(), color);
}
}
}
void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) const
void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) const
{
if (color == nullptr)
return;
@ -1396,10 +1397,10 @@ void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) con
Vec3f b_max = box.max.cast<float>();
Vec3f size = 0.2f * box.size().cast<float>();
::glEnable(GL_DEPTH_TEST);
glsafe(::glEnable(GL_DEPTH_TEST));
::glColor3fv(color);
::glLineWidth(2.0f * m_scale_factor);
glsafe(::glColor3fv(color));
glsafe(::glLineWidth(2.0f * m_scale_factor));
::glBegin(GL_LINES);
@ -1435,102 +1436,102 @@ void Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) con
::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1) - size(1), b_max(2));
::glVertex3f(b_min(0), b_max(1), b_max(2)); ::glVertex3f(b_min(0), b_max(1), b_max(2) - size(2));
::glEnd();
glsafe(::glEnd());
}
void Selection::_render_sidebar_position_hints(const std::string& sidebar_field) const
void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x"))
{
::glRotated(-90.0, 0.0, 0.0, 1.0);
_render_sidebar_position_hint(X);
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
render_sidebar_position_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
_render_sidebar_position_hint(Y);
render_sidebar_position_hint(Y);
else if (boost::ends_with(sidebar_field, "z"))
{
::glRotated(90.0, 1.0, 0.0, 0.0);
_render_sidebar_position_hint(Z);
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
render_sidebar_position_hint(Z);
}
}
void Selection::_render_sidebar_rotation_hints(const std::string& sidebar_field) const
void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x"))
{
::glRotated(90.0, 0.0, 1.0, 0.0);
_render_sidebar_rotation_hint(X);
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
render_sidebar_rotation_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
{
::glRotated(-90.0, 1.0, 0.0, 0.0);
_render_sidebar_rotation_hint(Y);
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
render_sidebar_rotation_hint(Y);
}
else if (boost::ends_with(sidebar_field, "z"))
_render_sidebar_rotation_hint(Z);
render_sidebar_rotation_hint(Z);
}
void Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const
{
bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling();
if (boost::ends_with(sidebar_field, "x") || uniform_scale)
{
::glPushMatrix();
::glRotated(-90.0, 0.0, 0.0, 1.0);
_render_sidebar_scale_hint(X);
::glPopMatrix();
glsafe(::glPushMatrix());
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
render_sidebar_scale_hint(X);
glsafe(::glPopMatrix());
}
if (boost::ends_with(sidebar_field, "y") || uniform_scale)
{
::glPushMatrix();
_render_sidebar_scale_hint(Y);
::glPopMatrix();
glsafe(::glPushMatrix());
render_sidebar_scale_hint(Y);
glsafe(::glPopMatrix());
}
if (boost::ends_with(sidebar_field, "z") || uniform_scale)
{
::glPushMatrix();
::glRotated(90.0, 1.0, 0.0, 0.0);
_render_sidebar_scale_hint(Z);
::glPopMatrix();
glsafe(::glPushMatrix());
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
render_sidebar_scale_hint(Z);
glsafe(::glPopMatrix());
}
}
void Selection::_render_sidebar_size_hints(const std::string& sidebar_field) const
void Selection::render_sidebar_size_hints(const std::string& sidebar_field) const
{
_render_sidebar_scale_hints(sidebar_field);
render_sidebar_scale_hints(sidebar_field);
}
void Selection::_render_sidebar_position_hint(Axis axis) const
void Selection::render_sidebar_position_hint(Axis axis) const
{
m_arrow.set_color(AXES_COLOR[axis], 3);
m_arrow.render();
}
void Selection::_render_sidebar_rotation_hint(Axis axis) const
void Selection::render_sidebar_rotation_hint(Axis axis) const
{
m_curved_arrow.set_color(AXES_COLOR[axis], 3);
m_curved_arrow.render();
::glRotated(180.0, 0.0, 0.0, 1.0);
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
m_curved_arrow.render();
}
void Selection::_render_sidebar_scale_hint(Axis axis) const
void Selection::render_sidebar_scale_hint(Axis axis) const
{
m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3);
::glTranslated(0.0, 5.0, 0.0);
glsafe(::glTranslated(0.0, 5.0, 0.0));
m_arrow.render();
::glTranslated(0.0, -10.0, 0.0);
::glRotated(180.0, 0.0, 0.0, 1.0);
glsafe(::glTranslated(0.0, -10.0, 0.0));
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
m_arrow.render();
}
void Selection::_render_sidebar_size_hint(Axis axis, double length) const
void Selection::render_sidebar_size_hint(Axis axis, double length) const
{
}
@ -1571,7 +1572,7 @@ static void verify_instances_rotation_synchronized(const Model &model, const GLV
}
#endif /* NDEBUG */
void Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation_type)
void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_type)
{
std::set<unsigned int> done; // prevent processing volumes twice
done.insert(m_list.begin(), m_list.end());
@ -1634,7 +1635,7 @@ void Selection::_synchronize_unselected_instances(SyncRotationType sync_rotation
#endif /* NDEBUG */
}
void Selection::_synchronize_unselected_volumes()
void Selection::synchronize_unselected_volumes()
{
for (unsigned int i : m_list)
{
@ -1667,7 +1668,7 @@ void Selection::_synchronize_unselected_volumes()
}
}
void Selection::_ensure_on_bed()
void Selection::ensure_on_bed()
{
typedef std::map<std::pair<int, int>, double> InstancesToZMap;
InstancesToZMap instances_min_z;
@ -1695,7 +1696,7 @@ void Selection::_ensure_on_bed()
}
}
bool Selection::_is_from_fully_selected_instance(unsigned int volume_idx) const
bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const
{
struct SameInstance
{

View file

@ -267,27 +267,27 @@ public:
bool requires_local_axes() const;
private:
void _update_valid();
void _update_type();
void _set_caches();
void _add_volume(unsigned int volume_idx);
void _add_instance(unsigned int object_idx, unsigned int instance_idx);
void _add_object(unsigned int object_idx);
void _remove_volume(unsigned int volume_idx);
void _remove_instance(unsigned int object_idx, unsigned int instance_idx);
void _remove_object(unsigned int object_idx);
void _calc_bounding_box() const;
void _render_selected_volumes() const;
void _render_synchronized_volumes() const;
void _render_bounding_box(const BoundingBoxf3& box, float* color) const;
void _render_sidebar_position_hints(const std::string& sidebar_field) const;
void _render_sidebar_rotation_hints(const std::string& sidebar_field) const;
void _render_sidebar_scale_hints(const std::string& sidebar_field) const;
void _render_sidebar_size_hints(const std::string& sidebar_field) const;
void _render_sidebar_position_hint(Axis axis) const;
void _render_sidebar_rotation_hint(Axis axis) const;
void _render_sidebar_scale_hint(Axis axis) const;
void _render_sidebar_size_hint(Axis axis, double length) const;
void update_valid();
void update_type();
void set_caches();
void do_add_volume(unsigned int volume_idx);
void do_add_instance(unsigned int object_idx, unsigned int instance_idx);
void do_add_object(unsigned int object_idx);
void do_remove_volume(unsigned int volume_idx);
void do_remove_instance(unsigned int object_idx, unsigned int instance_idx);
void do_remove_object(unsigned int object_idx);
void calc_bounding_box() const;
void render_selected_volumes() const;
void render_synchronized_volumes() const;
void render_bounding_box(const BoundingBoxf3& box, float* color) const;
void render_sidebar_position_hints(const std::string& sidebar_field) const;
void render_sidebar_rotation_hints(const std::string& sidebar_field) const;
void render_sidebar_scale_hints(const std::string& sidebar_field) const;
void render_sidebar_size_hints(const std::string& sidebar_field) const;
void render_sidebar_position_hint(Axis axis) const;
void render_sidebar_rotation_hint(Axis axis) const;
void render_sidebar_scale_hint(Axis axis) const;
void render_sidebar_size_hint(Axis axis, double length) const;
enum SyncRotationType {
// Do not synchronize rotation. Either not rotating at all, or rotating by world Z axis.
SYNC_ROTATION_NONE = 0,
@ -296,10 +296,10 @@ private:
// Synchronize after rotation by an axis not parallel with Z.
SYNC_ROTATION_GENERAL = 2,
};
void _synchronize_unselected_instances(SyncRotationType sync_rotation_type);
void _synchronize_unselected_volumes();
void _ensure_on_bed();
bool _is_from_fully_selected_instance(unsigned int volume_idx) const;
void synchronize_unselected_instances(SyncRotationType sync_rotation_type);
void synchronize_unselected_volumes();
void ensure_on_bed();
bool is_from_fully_selected_instance(unsigned int volume_idx) const;
};
} // namespace GUI