NEW: upgrade GLModel and so on
Jira: STUDIO-6166 most of code from PrusaSlicer thanks for PrusaSlicer and enricoturri1966 commit f8ce187262df8ef588f649c414a095c971f36e67 Author: enricoturri1966 <enricoturri@seznam.cz> Date: Wed Mar 9 11:51:02 2022 +0100 Tech ENABLE_LEGACY_OPENGL_REMOVAL - Refactoring of GLModel to automatically detect the data type to use into the index buffer in dependence of vertices count Change-Id: I8b05c5c01c1d06cc24d1981479f44c016a46b2dd
This commit is contained in:
parent
626e2a9f79
commit
98faf48787
|
@ -16,6 +16,424 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec2f &position)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P2);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec2f &position, const Vec2f &tex_coord)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P2T2);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(tex_coord.x());
|
||||||
|
vertices.emplace_back(tex_coord.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec3f &position)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P3);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(position.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec3f &position, const Vec2f &tex_coord)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P3T2);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(position.z());
|
||||||
|
vertices.emplace_back(tex_coord.x());
|
||||||
|
vertices.emplace_back(tex_coord.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec3f &position, const Vec3f &normal)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P3N3);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(position.z());
|
||||||
|
vertices.emplace_back(normal.x());
|
||||||
|
vertices.emplace_back(normal.y());
|
||||||
|
vertices.emplace_back(normal.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec3f &position, const Vec3f &normal, const Vec2f &tex_coord)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P3N3T2);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(position.z());
|
||||||
|
vertices.emplace_back(normal.x());
|
||||||
|
vertices.emplace_back(normal.y());
|
||||||
|
vertices.emplace_back(normal.z());
|
||||||
|
vertices.emplace_back(tex_coord.x());
|
||||||
|
vertices.emplace_back(tex_coord.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_vertex(const Vec4f &position)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P4);
|
||||||
|
vertices.emplace_back(position.x());
|
||||||
|
vertices.emplace_back(position.y());
|
||||||
|
vertices.emplace_back(position.z());
|
||||||
|
vertices.emplace_back(position.w());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_index(unsigned int id) { indices.emplace_back(id); }
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_line(unsigned int id1, unsigned int id2)
|
||||||
|
{
|
||||||
|
indices.emplace_back(id1);
|
||||||
|
indices.emplace_back(id2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::add_triangle(unsigned int id1, unsigned int id2, unsigned int id3)
|
||||||
|
{
|
||||||
|
indices.emplace_back(id1);
|
||||||
|
indices.emplace_back(id2);
|
||||||
|
indices.emplace_back(id3);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2f GLModel::Geometry::extract_position_2(size_t id) const
|
||||||
|
{
|
||||||
|
const size_t p_stride = position_stride_floats(format);
|
||||||
|
if (p_stride != 2) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices_count() <= id) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
const float *start = &vertices[id * vertex_stride_floats(format) + position_offset_floats(format)];
|
||||||
|
return {*(start + 0), *(start + 1)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f GLModel::Geometry::extract_position_3(size_t id) const
|
||||||
|
{
|
||||||
|
const size_t p_stride = position_stride_floats(format);
|
||||||
|
if (p_stride != 3) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices_count() <= id) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
const float *start = &vertices[id * vertex_stride_floats(format) + position_offset_floats(format)];
|
||||||
|
return {*(start + 0), *(start + 1), *(start + 2)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f GLModel::Geometry::extract_normal_3(size_t id) const
|
||||||
|
{
|
||||||
|
const size_t n_stride = normal_stride_floats(format);
|
||||||
|
if (n_stride != 3) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices_count() <= id) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
const float *start = &vertices[id * vertex_stride_floats(format) + normal_offset_floats(format)];
|
||||||
|
return {*(start + 0), *(start + 1), *(start + 2)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2f GLModel::Geometry::extract_tex_coord_2(size_t id) const
|
||||||
|
{
|
||||||
|
const size_t t_stride = tex_coord_stride_floats(format);
|
||||||
|
if (t_stride != 2) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices_count() <= id) {
|
||||||
|
assert(false);
|
||||||
|
return {FLT_MAX, FLT_MAX};
|
||||||
|
}
|
||||||
|
|
||||||
|
const float *start = &vertices[id * vertex_stride_floats(format) + tex_coord_offset_floats(format)];
|
||||||
|
return {*(start + 0), *(start + 1)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::set_vertex(size_t id, const Vec3f &position, const Vec3f &normal)
|
||||||
|
{
|
||||||
|
assert(format.vertex_layout == EVertexLayout::P3N3);
|
||||||
|
assert(id < vertices_count());
|
||||||
|
if (id < vertices_count()) {
|
||||||
|
float *start = &vertices[id * vertex_stride_floats(format)];
|
||||||
|
*(start + 0) = position.x();
|
||||||
|
*(start + 1) = position.y();
|
||||||
|
*(start + 2) = position.z();
|
||||||
|
*(start + 3) = normal.x();
|
||||||
|
*(start + 4) = normal.y();
|
||||||
|
*(start + 5) = normal.z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::set_index(size_t id, unsigned int index)
|
||||||
|
{
|
||||||
|
assert(id < indices_count());
|
||||||
|
if (id < indices_count()) indices[id] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GLModel::Geometry::extract_index(size_t id) const
|
||||||
|
{
|
||||||
|
if (indices_count() <= id) {
|
||||||
|
assert(false);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::Geometry::remove_vertex(size_t id)
|
||||||
|
{
|
||||||
|
assert(id < vertices_count());
|
||||||
|
if (id < vertices_count()) {
|
||||||
|
const size_t stride = vertex_stride_floats(format);
|
||||||
|
std::vector<float>::const_iterator it = vertices.begin() + id * stride;
|
||||||
|
vertices.erase(it, it + stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indexed_triangle_set GLModel::Geometry::get_as_indexed_triangle_set() const
|
||||||
|
{
|
||||||
|
indexed_triangle_set its;
|
||||||
|
its.vertices.reserve(vertices_count());
|
||||||
|
for (size_t i = 0; i < vertices_count(); ++i) { its.vertices.emplace_back(extract_position_3(i)); }
|
||||||
|
its.indices.reserve(indices_count() / 3);
|
||||||
|
for (size_t i = 0; i < indices_count() / 3; ++i) {
|
||||||
|
const size_t tri_id = i * 3;
|
||||||
|
its.indices.emplace_back(extract_index(tri_id), extract_index(tri_id + 1), extract_index(tri_id + 2));
|
||||||
|
}
|
||||||
|
return its;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::vertex_stride_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2: {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P2T2: {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3: {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3T2: {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3N3: {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::position_stride_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2:
|
||||||
|
case EVertexLayout::P2T2: {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::position_offset_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2:
|
||||||
|
case EVertexLayout::P2T2:
|
||||||
|
case EVertexLayout::P3:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2:
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::normal_stride_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::normal_offset_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::tex_coord_stride_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2T2:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::tex_coord_offset_floats(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2T2: {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3T2: {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GLModel::Geometry::index_stride_bytes(const Geometry &data)
|
||||||
|
{
|
||||||
|
switch (data.index_type) {
|
||||||
|
case EIndexType::UINT: {
|
||||||
|
return sizeof(unsigned int);
|
||||||
|
}
|
||||||
|
case EIndexType::USHORT: {
|
||||||
|
return sizeof(unsigned short);
|
||||||
|
}
|
||||||
|
case EIndexType::UBYTE: {
|
||||||
|
return sizeof(unsigned char);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLModel::Geometry::has_position(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2:
|
||||||
|
case EVertexLayout::P2T2:
|
||||||
|
case EVertexLayout::P3:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2:
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLModel::Geometry::has_normal(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2:
|
||||||
|
case EVertexLayout::P2T2:
|
||||||
|
case EVertexLayout::P3:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLModel::Geometry::has_tex_coord(const Format &format)
|
||||||
|
{
|
||||||
|
switch (format.vertex_layout) {
|
||||||
|
case EVertexLayout::P2T2:
|
||||||
|
case EVertexLayout::P3T2:
|
||||||
|
case EVertexLayout::P3N3T2: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case EVertexLayout::P2:
|
||||||
|
case EVertexLayout::P3:
|
||||||
|
case EVertexLayout::P3N3:
|
||||||
|
case EVertexLayout::P4: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
size_t GLModel::InitializationData::vertices_count() const
|
size_t GLModel::InitializationData::vertices_count() const
|
||||||
{
|
{
|
||||||
|
@ -35,6 +453,46 @@ size_t GLModel::InitializationData::indices_count() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLModel::~GLModel()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
if (mesh) { delete mesh; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLModel::init_from(Geometry &&data, bool generate_mesh)
|
||||||
|
{
|
||||||
|
if (is_initialized()) {
|
||||||
|
// call reset() if you want to reuse this model
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.vertices.empty() || data.indices.empty()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_render_data.clear();
|
||||||
|
m_render_data.push_back(RenderData());
|
||||||
|
m_render_data.back().indices_count = data.indices.size();
|
||||||
|
m_render_data.back().type = data.format.type;
|
||||||
|
m_render_data.back().color = data.color.get_data();
|
||||||
|
if (generate_mesh) {
|
||||||
|
if (!mesh) { mesh = new TriangleMesh(); }
|
||||||
|
mesh->its = std::move(data.get_as_indexed_triangle_set());
|
||||||
|
}
|
||||||
|
m_render_data.back().geometry = std::move(data);
|
||||||
|
// update bounding box
|
||||||
|
for (size_t i = 0; i < data.vertices_count(); ++i) {
|
||||||
|
const size_t position_stride = Geometry::position_stride_floats(data.format);
|
||||||
|
if (position_stride == 3)
|
||||||
|
m_bounding_box.merge(m_render_data.back().geometry.extract_position_3(i).cast<double>());
|
||||||
|
else if (position_stride == 2) {
|
||||||
|
const Vec2f position = m_render_data.back().geometry.extract_position_2(i);
|
||||||
|
m_bounding_box.merge(Vec3f(position.x(), position.y(), 0.0f).cast<double>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLModel::init_from(const InitializationData& data)
|
void GLModel::init_from(const InitializationData& data)
|
||||||
{
|
{
|
||||||
if (!m_render_data.empty()) // call reset() if you want to reuse this model
|
if (!m_render_data.empty()) // call reset() if you want to reuse this model
|
||||||
|
@ -193,8 +651,17 @@ void GLModel::render() const
|
||||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||||
|
|
||||||
for (const RenderData& data : m_render_data) {
|
for (const RenderData& data : m_render_data) {
|
||||||
if (data.vbo_id == 0 || data.ibo_id == 0)
|
// sends data to gpu if not done yet
|
||||||
|
if (data.vbo_id == 0 || data.ibo_id == 0) {
|
||||||
|
auto origin_data = const_cast<RenderData *>(&data);
|
||||||
|
if (data.geometry.vertices_count() > 0 && data.geometry.indices_count() > 0
|
||||||
|
&& !send_to_gpu(*origin_data, data.geometry.vertices, data.geometry.indices))
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
bool has_normal = true;
|
||||||
|
if (data.geometry.vertices_count() > 0) {
|
||||||
|
has_normal = Geometry::has_normal(data.geometry.format);
|
||||||
|
}
|
||||||
|
|
||||||
GLenum mode;
|
GLenum mode;
|
||||||
switch (data.type)
|
switch (data.type)
|
||||||
|
@ -207,11 +674,16 @@ void GLModel::render() const
|
||||||
}
|
}
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, data.vbo_id));
|
||||||
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)0));
|
if (has_normal) {
|
||||||
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
|
glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void *) 0));
|
||||||
|
glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), (const void *) (3 * sizeof(float))));
|
||||||
|
|
||||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||||
|
} else {
|
||||||
|
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void *) 0));
|
||||||
|
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||||
|
}
|
||||||
|
|
||||||
if (shader != nullptr)
|
if (shader != nullptr)
|
||||||
shader->set_uniform("uniform_color", data.color);
|
shader->set_uniform("uniform_color", data.color);
|
||||||
|
@ -306,10 +778,17 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
|
bool GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices) const
|
||||||
{
|
{
|
||||||
assert(data.vbo_id == 0);
|
if (data.vbo_id > 0 || data.ibo_id > 0) {
|
||||||
assert(data.ibo_id == 0);
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices.empty() || indices.empty()) {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// vertex data -> send to gpu
|
// vertex data -> send to gpu
|
||||||
glsafe(::glGenBuffers(1, &data.vbo_id));
|
glsafe(::glGenBuffers(1, &data.vbo_id));
|
||||||
|
@ -322,6 +801,7 @@ void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices,
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ibo_id));
|
||||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW));
|
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW));
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
|
GLModel::InitializationData stilized_arrow(int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
|
||||||
|
@ -744,5 +1224,181 @@ GLModel::InitializationData diamond(int resolution)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLModel::Geometry smooth_sphere(unsigned int resolution, float radius)
|
||||||
|
{
|
||||||
|
resolution = std::max<unsigned int>(4, resolution);
|
||||||
|
|
||||||
|
const unsigned int sectorCount = resolution;
|
||||||
|
const unsigned int stackCount = resolution;
|
||||||
|
|
||||||
|
const float sectorStep = float(2.0 * M_PI / sectorCount);
|
||||||
|
const float stackStep = float(M_PI / stackCount);
|
||||||
|
|
||||||
|
GLModel::Geometry data;
|
||||||
|
data.format = {GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||||
|
data.reserve_vertices((stackCount - 1) * sectorCount + 2);
|
||||||
|
data.reserve_indices((2 * (stackCount - 1) * sectorCount) * 3);
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
for (unsigned int i = 0; i <= stackCount; ++i) {
|
||||||
|
// from pi/2 to -pi/2
|
||||||
|
const double stackAngle = 0.5 * M_PI - stackStep * i;
|
||||||
|
const double xy = double(radius) * ::cos(stackAngle);
|
||||||
|
const double z = double(radius) * ::sin(stackAngle);
|
||||||
|
if (i == 0 || i == stackCount) {
|
||||||
|
const Vec3f v(float(xy), 0.0f, float(z));
|
||||||
|
data.add_vertex(v, (Vec3f) v.normalized());
|
||||||
|
} else {
|
||||||
|
for (unsigned int j = 0; j < sectorCount; ++j) {
|
||||||
|
// from 0 to 2pi
|
||||||
|
const double sectorAngle = sectorStep * j;
|
||||||
|
const Vec3f v(float(xy * std::cos(sectorAngle)), float(xy * std::sin(sectorAngle)), float(z));
|
||||||
|
data.add_vertex(v, (Vec3f) v.normalized());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// triangles
|
||||||
|
for (unsigned int i = 0; i < stackCount; ++i) {
|
||||||
|
// Beginning of current stack.
|
||||||
|
unsigned int k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount);
|
||||||
|
const unsigned int k1_first = k1;
|
||||||
|
// Beginning of next stack.
|
||||||
|
unsigned int k2 = (i == 0) ? 1 : (k1 + sectorCount);
|
||||||
|
const unsigned int k2_first = k2;
|
||||||
|
for (unsigned int j = 0; j < sectorCount; ++j) {
|
||||||
|
// 2 triangles per sector excluding first and last stacks
|
||||||
|
unsigned int k1_next = k1;
|
||||||
|
unsigned int k2_next = k2;
|
||||||
|
if (i != 0) {
|
||||||
|
k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1);
|
||||||
|
data.add_triangle(k1, k2, k1_next);
|
||||||
|
}
|
||||||
|
if (i + 1 != stackCount) {
|
||||||
|
k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1);
|
||||||
|
data.add_triangle(k1_next, k2, k2_next);
|
||||||
|
}
|
||||||
|
k1 = k1_next;
|
||||||
|
k2 = k2_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLModel::Geometry smooth_cylinder(unsigned int resolution, float radius, float height)
|
||||||
|
{
|
||||||
|
resolution = std::max<unsigned int>(4, resolution);
|
||||||
|
|
||||||
|
const unsigned int sectorCount = resolution;
|
||||||
|
const float sectorStep = 2.0f * float(M_PI) / float(sectorCount);
|
||||||
|
|
||||||
|
GLModel::Geometry data;
|
||||||
|
data.format = {GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||||
|
data.reserve_vertices(sectorCount * 4 + 2);
|
||||||
|
data.reserve_indices(sectorCount * 4 * 3);
|
||||||
|
|
||||||
|
auto generate_vertices_on_circle = [sectorCount, sectorStep](float radius) {
|
||||||
|
std::vector<Vec3f> ret;
|
||||||
|
ret.reserve(sectorCount);
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) {
|
||||||
|
// from 0 to 2pi
|
||||||
|
const float sectorAngle = sectorStep * i;
|
||||||
|
ret.emplace_back(radius * std::cos(sectorAngle), radius * std::sin(sectorAngle), 0.0f);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<Vec3f> base_vertices = generate_vertices_on_circle(radius);
|
||||||
|
const Vec3f h = height * Vec3f::UnitZ();
|
||||||
|
|
||||||
|
// stem vertices
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) {
|
||||||
|
const Vec3f &v = base_vertices[i];
|
||||||
|
const Vec3f n = v.normalized();
|
||||||
|
data.add_vertex(v, n);
|
||||||
|
data.add_vertex(v + h, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stem triangles
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) {
|
||||||
|
unsigned int v1 = i * 2;
|
||||||
|
unsigned int v2 = (i < sectorCount - 1) ? v1 + 2 : 0;
|
||||||
|
unsigned int v3 = v2 + 1;
|
||||||
|
unsigned int v4 = v1 + 1;
|
||||||
|
data.add_triangle(v1, v2, v3);
|
||||||
|
data.add_triangle(v1, v3, v4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom cap vertices
|
||||||
|
Vec3f cap_center = Vec3f::Zero();
|
||||||
|
unsigned int cap_center_id = data.vertices_count();
|
||||||
|
Vec3f normal = -Vec3f::UnitZ();
|
||||||
|
|
||||||
|
data.add_vertex(cap_center, normal);
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) { data.add_vertex(base_vertices[i], normal); }
|
||||||
|
|
||||||
|
// bottom cap triangles
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) { data.add_triangle(cap_center_id, (i < sectorCount - 1) ? cap_center_id + i + 2 : cap_center_id + 1, cap_center_id + i + 1); }
|
||||||
|
|
||||||
|
// top cap vertices
|
||||||
|
cap_center += h;
|
||||||
|
cap_center_id = data.vertices_count();
|
||||||
|
normal = -normal;
|
||||||
|
|
||||||
|
data.add_vertex(cap_center, normal);
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) { data.add_vertex(base_vertices[i] + h, normal); }
|
||||||
|
|
||||||
|
// top cap triangles
|
||||||
|
for (unsigned int i = 0; i < sectorCount; ++i) { data.add_triangle(cap_center_id, cap_center_id + i + 1, (i < sectorCount - 1) ? cap_center_id + i + 2 : cap_center_id + 1); }
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int secondary_resolution, float radius, float thickness)
|
||||||
|
{
|
||||||
|
const unsigned int torus_sector_count = std::max<unsigned int>(4, primary_resolution);
|
||||||
|
const float torus_sector_step = 2.0f * float(M_PI) / float(torus_sector_count);
|
||||||
|
const unsigned int section_sector_count = std::max<unsigned int>(4, secondary_resolution);
|
||||||
|
const float section_sector_step = 2.0f * float(M_PI) / float(section_sector_count);
|
||||||
|
|
||||||
|
GLModel::Geometry data;
|
||||||
|
data.format = {GLModel::PrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3};
|
||||||
|
data.reserve_vertices(torus_sector_count * section_sector_count);
|
||||||
|
data.reserve_indices(torus_sector_count * section_sector_count * 2 * 3);
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||||
|
const float section_angle = torus_sector_step * i;
|
||||||
|
const float csa = std::cos(section_angle);
|
||||||
|
const float ssa = std::sin(section_angle);
|
||||||
|
const Vec3f section_center(radius * csa, radius * ssa, 0.0f);
|
||||||
|
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||||
|
const float circle_angle = section_sector_step * j;
|
||||||
|
const float thickness_xy = thickness * std::cos(circle_angle);
|
||||||
|
const float thickness_z = thickness * std::sin(circle_angle);
|
||||||
|
const Vec3f v(thickness_xy * csa, thickness_xy * ssa, thickness_z);
|
||||||
|
data.add_vertex(section_center + v, (Vec3f) v.normalized());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// triangles
|
||||||
|
for (unsigned int i = 0; i < torus_sector_count; ++i) {
|
||||||
|
const unsigned int ii = i * section_sector_count;
|
||||||
|
const unsigned int ii_next = ((i + 1) % torus_sector_count) * section_sector_count;
|
||||||
|
for (unsigned int j = 0; j < section_sector_count; ++j) {
|
||||||
|
const unsigned int j_next = (j + 1) % section_sector_count;
|
||||||
|
const unsigned int i0 = ii + j;
|
||||||
|
const unsigned int i1 = ii_next + j;
|
||||||
|
const unsigned int i2 = ii_next + j_next;
|
||||||
|
const unsigned int i3 = ii + j_next;
|
||||||
|
data.add_triangle(i0, i1, i2);
|
||||||
|
data.add_triangle(i0, i2, i3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -28,13 +28,110 @@ namespace GUI {
|
||||||
LineLoop
|
LineLoop
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Geometry
|
||||||
|
{
|
||||||
|
// enum class EPrimitiveType : unsigned char { Points, Triangles, TriangleStrip, TriangleFan, Lines, LineStrip, LineLoop };
|
||||||
|
enum class EVertexLayout : unsigned char {
|
||||||
|
P2, // position 2 floats
|
||||||
|
P2T2, // position 2 floats + texture coords 2 floats
|
||||||
|
P3, // position 3 floats
|
||||||
|
P3T2, // position 3 floats + texture coords 2 floats
|
||||||
|
P3N3, // position 3 floats + normal 3 floats
|
||||||
|
P3N3T2, // position 3 floats + normal 3 floats + texture coords 2 floats
|
||||||
|
P4, // position 4 floats
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EIndexType : unsigned char {
|
||||||
|
UINT, // unsigned int
|
||||||
|
USHORT, // unsigned short
|
||||||
|
UBYTE // unsigned byte
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Format
|
||||||
|
{
|
||||||
|
PrimitiveType type{PrimitiveType::Triangles};
|
||||||
|
EVertexLayout vertex_layout{EVertexLayout::P3N3};
|
||||||
|
};
|
||||||
|
|
||||||
|
Format format;
|
||||||
|
std::vector<float> vertices;
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
EIndexType index_type{EIndexType::UINT};
|
||||||
|
ColorRGBA color{ColorRGBA::BLACK()};
|
||||||
|
|
||||||
|
void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); }
|
||||||
|
void reserve_indices(size_t indices_count) { indices.reserve(indices_count); }
|
||||||
|
|
||||||
|
void add_vertex(const Vec2f &position); // EVertexLayout::P2
|
||||||
|
void add_vertex(const Vec2f &position, const Vec2f &tex_coord); // EVertexLayout::P2T2
|
||||||
|
void add_vertex(const Vec3f &position); // EVertexLayout::P3
|
||||||
|
void add_vertex(const Vec3f &position, const Vec2f &tex_coord); // EVertexLayout::P3T2
|
||||||
|
void add_vertex(const Vec3f &position, const Vec3f &normal); // EVertexLayout::P3N3
|
||||||
|
void add_vertex(const Vec3f &position, const Vec3f &normal, const Vec2f &tex_coord); // EVertexLayout::P3N3T2
|
||||||
|
void add_vertex(const Vec4f &position); // EVertexLayout::P4
|
||||||
|
|
||||||
|
void set_vertex(size_t id, const Vec3f &position, const Vec3f &normal); // EVertexLayout::P3N3
|
||||||
|
|
||||||
|
void set_index(size_t id, unsigned int index);
|
||||||
|
|
||||||
|
void add_index(unsigned int id);
|
||||||
|
void add_line(unsigned int id1, unsigned int id2);
|
||||||
|
void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
|
||||||
|
|
||||||
|
Vec2f extract_position_2(size_t id) const;
|
||||||
|
Vec3f extract_position_3(size_t id) const;
|
||||||
|
Vec3f extract_normal_3(size_t id) const;
|
||||||
|
Vec2f extract_tex_coord_2(size_t id) const;
|
||||||
|
|
||||||
|
unsigned int extract_index(size_t id) const;
|
||||||
|
|
||||||
|
void remove_vertex(size_t id);
|
||||||
|
|
||||||
|
bool is_empty() const { return vertices_count() == 0 || indices_count() == 0; }
|
||||||
|
|
||||||
|
size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); }
|
||||||
|
size_t indices_count() const { return indices.size(); }
|
||||||
|
|
||||||
|
size_t vertices_size_floats() const { return vertices.size(); }
|
||||||
|
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
|
||||||
|
size_t indices_size_bytes() const { return indices.size() * index_stride_bytes(*this); }
|
||||||
|
|
||||||
|
indexed_triangle_set get_as_indexed_triangle_set() const;
|
||||||
|
|
||||||
|
static size_t vertex_stride_floats(const Format &format);
|
||||||
|
static size_t vertex_stride_bytes(const Format &format) { return vertex_stride_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t position_stride_floats(const Format &format);
|
||||||
|
static size_t position_stride_bytes(const Format &format) { return position_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t position_offset_floats(const Format &format);
|
||||||
|
static size_t position_offset_bytes(const Format &format) { return position_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t normal_stride_floats(const Format &format);
|
||||||
|
static size_t normal_stride_bytes(const Format &format) { return normal_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t normal_offset_floats(const Format &format);
|
||||||
|
static size_t normal_offset_bytes(const Format &format) { return normal_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t tex_coord_stride_floats(const Format &format);
|
||||||
|
static size_t tex_coord_stride_bytes(const Format &format) { return tex_coord_stride_floats(format) * sizeof(float); }
|
||||||
|
static size_t tex_coord_offset_floats(const Format &format);
|
||||||
|
static size_t tex_coord_offset_bytes(const Format &format) { return tex_coord_offset_floats(format) * sizeof(float); }
|
||||||
|
|
||||||
|
static size_t index_stride_bytes(const Geometry &data);
|
||||||
|
|
||||||
|
static bool has_position(const Format &format);
|
||||||
|
static bool has_normal(const Format &format);
|
||||||
|
static bool has_tex_coord(const Format &format);
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderData
|
struct RenderData
|
||||||
{
|
{
|
||||||
|
Geometry geometry;
|
||||||
|
|
||||||
PrimitiveType type;
|
PrimitiveType type;
|
||||||
unsigned int vbo_id{ 0 };
|
unsigned int vbo_id{0};
|
||||||
unsigned int ibo_id{ 0 };
|
unsigned int ibo_id{0};
|
||||||
size_t indices_count{ 0 };
|
size_t indices_count{0};
|
||||||
std::array<float, 4> color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
std::array<float, 4> color{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InitializationData
|
struct InitializationData
|
||||||
|
@ -66,8 +163,11 @@ namespace GUI {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLModel() = default;
|
GLModel() = default;
|
||||||
virtual ~GLModel() { reset(); }
|
virtual ~GLModel();
|
||||||
|
|
||||||
|
TriangleMesh *mesh{nullptr};
|
||||||
|
|
||||||
|
void init_from(Geometry &&data, bool generate_mesh = false);
|
||||||
void init_from(const InitializationData& data);
|
void init_from(const InitializationData& data);
|
||||||
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
|
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
|
||||||
void init_from(const indexed_triangle_set& its);
|
void init_from(const indexed_triangle_set& its);
|
||||||
|
@ -87,7 +187,7 @@ namespace GUI {
|
||||||
const std::string& get_filename() const { return m_filename; }
|
const std::string& get_filename() const { return m_filename; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices);
|
bool send_to_gpu(RenderData &data, const std::vector<float> &vertices, const std::vector<unsigned int> &indices) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
|
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
|
||||||
|
@ -113,7 +213,19 @@ namespace GUI {
|
||||||
// the diamond is contained into a box with size [1, 1, 1]
|
// the diamond is contained into a box with size [1, 1, 1]
|
||||||
GLModel::InitializationData diamond(int resolution);
|
GLModel::InitializationData diamond(int resolution);
|
||||||
|
|
||||||
} // namespace GUI
|
// create a sphere with smooth normals
|
||||||
|
// the origin of the sphere is in its center
|
||||||
|
GLModel::Geometry smooth_sphere(unsigned int resolution, float radius);
|
||||||
|
// create a cylinder with smooth normals
|
||||||
|
// the axis of the cylinder is the Z axis
|
||||||
|
// the origin of the cylinder is the center of its bottom cap face
|
||||||
|
GLModel::Geometry smooth_cylinder(unsigned int resolution, float radius, float height);
|
||||||
|
// create a torus with smooth normals
|
||||||
|
// the axis of the torus is the Z axis
|
||||||
|
// the origin of the torus is in its center
|
||||||
|
GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int secondary_resolution, float radius, float thickness);
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif // slic3r_GLModel_hpp_
|
#endif // slic3r_GLModel_hpp_
|
||||||
|
|
|
@ -5983,6 +5983,12 @@ Sidebar& GUI_App::sidebar()
|
||||||
return plater_->sidebar();
|
return plater_->sidebar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GizmoObjectManipulation *GUI_App::obj_manipul()
|
||||||
|
{
|
||||||
|
// If this method is called before plater_ has been initialized, return nullptr (to avoid a crash)
|
||||||
|
return (plater_ != nullptr) ? &plater_->get_view3D_canvas3D()->get_gizmos_manager().get_object_manipulation() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
ObjectSettings* GUI_App::obj_settings()
|
ObjectSettings* GUI_App::obj_settings()
|
||||||
{
|
{
|
||||||
return sidebar().obj_settings();
|
return sidebar().obj_settings();
|
||||||
|
|
|
@ -130,6 +130,7 @@ enum CameraMenuIDs {
|
||||||
|
|
||||||
class Tab;
|
class Tab;
|
||||||
class ConfigWizard;
|
class ConfigWizard;
|
||||||
|
class GizmoObjectManipulation;
|
||||||
|
|
||||||
static wxString dots("...", wxConvUTF8);
|
static wxString dots("...", wxConvUTF8);
|
||||||
|
|
||||||
|
@ -527,6 +528,7 @@ public:
|
||||||
#endif /* __APPLE */
|
#endif /* __APPLE */
|
||||||
|
|
||||||
Sidebar& sidebar();
|
Sidebar& sidebar();
|
||||||
|
GizmoObjectManipulation *obj_manipul();
|
||||||
ObjectSettings* obj_settings();
|
ObjectSettings* obj_settings();
|
||||||
ObjectList* obj_list();
|
ObjectList* obj_list();
|
||||||
ObjectLayers* obj_layers();
|
ObjectLayers* obj_layers();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "GLGizmoRotate.hpp"
|
#include "GLGizmoRotate.hpp"
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/CutUtils.hpp"
|
#include "libslic3r/CutUtils.hpp"
|
||||||
#include "slic3r/GUI/MeshUtils.hpp"
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
enum class CutConnectorType : int;
|
enum class CutConnectorType : int;
|
||||||
class ModelVolume;
|
class ModelVolume;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "slic3r/GUI/I18N.hpp"
|
#include "slic3r/GUI/I18N.hpp"
|
||||||
#include "slic3r/GUI/GLModel.hpp"
|
#include "slic3r/GUI/GLModel.hpp"
|
||||||
|
#include "slic3r/GUI/MeshUtils.hpp"
|
||||||
|
|
||||||
#include <cereal/archives/binary.hpp>
|
#include <cereal/archives/binary.hpp>
|
||||||
|
|
||||||
|
@ -114,6 +115,21 @@ protected:
|
||||||
std::string m_icon_filename;
|
std::string m_icon_filename;
|
||||||
unsigned int m_sprite_id;
|
unsigned int m_sprite_id;
|
||||||
int m_hover_id;
|
int m_hover_id;
|
||||||
|
enum GripperType {
|
||||||
|
UNDEFINE,
|
||||||
|
POINT,
|
||||||
|
EDGE,
|
||||||
|
CIRCLE,
|
||||||
|
CIRCLE_1,
|
||||||
|
CIRCLE_2,
|
||||||
|
PLANE,
|
||||||
|
PLANE_1,
|
||||||
|
PLANE_2,
|
||||||
|
SPHERE_1,
|
||||||
|
SPHERE_2,
|
||||||
|
};
|
||||||
|
std::map<GripperType, std::shared_ptr<PickRaycaster>> m_gripper_id_raycast_map;
|
||||||
|
|
||||||
bool m_dragging;
|
bool m_dragging;
|
||||||
std::array<float, 4> m_base_color;
|
std::array<float, 4> m_base_color;
|
||||||
std::array<float, 4> m_drag_color;
|
std::array<float, 4> m_drag_color;
|
||||||
|
|
Loading…
Reference in New Issue