Measuring: circle feature rendered using a torus
This commit is contained in:
parent
8f06086679
commit
26650a2658
@ -2292,7 +2292,7 @@ GLModel::Geometry smooth_cylinder(unsigned int resolution, float radius, float h
|
||||
ret.reserve(sectorCount);
|
||||
for (unsigned int i = 0; i < sectorCount; ++i) {
|
||||
// from 0 to 2pi
|
||||
const float sectorAngle = (i != sectorCount) ? sectorStep * i : 0.0f;
|
||||
const float sectorAngle = sectorStep * i;
|
||||
ret.emplace_back(radius * std::cos(sectorAngle), radius * std::sin(sectorAngle), 0.0f);
|
||||
}
|
||||
return ret;
|
||||
@ -2351,6 +2351,51 @@ GLModel::Geometry smooth_cylinder(unsigned int resolution, float radius, float h
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
GLModel::Geometry smooth_torus(unsigned int primary_resolution, unsigned int secondary_resolution, float radius, float thickness)
|
||||
{
|
||||
primary_resolution = std::max<unsigned int>(4, primary_resolution);
|
||||
secondary_resolution = std::max<unsigned int>(4, secondary_resolution);
|
||||
const unsigned int torusSectorCount = primary_resolution;
|
||||
const float torusSectorStep = 2.0f * float(M_PI) / float(torusSectorCount);
|
||||
const unsigned int sectionSectorCount = secondary_resolution;
|
||||
const float sectionSectorStep = 2.0f * float(M_PI) / float(sectionSectorCount);
|
||||
|
||||
GLModel::Geometry data;
|
||||
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
|
||||
data.reserve_vertices(torusSectorCount * sectionSectorCount);
|
||||
data.reserve_indices(torusSectorCount * sectionSectorCount * 2 * 3);
|
||||
|
||||
// vertices
|
||||
for (unsigned int i = 0; i < torusSectorCount; ++i) {
|
||||
const float sectionAngle = torusSectorStep * i;
|
||||
const Vec3f sectionCenter(radius * std::cos(sectionAngle), radius * std::sin(sectionAngle), 0.0f);
|
||||
for (unsigned int j = 0; j < sectionSectorCount; ++j) {
|
||||
const float circleAngle = sectionSectorStep * j;
|
||||
const float thickness_xy = thickness * std::cos(circleAngle);
|
||||
const float thickness_z = thickness * std::sin(circleAngle);
|
||||
const Vec3f v(thickness_xy * std::cos(sectionAngle), thickness_xy * std::sin(sectionAngle), thickness_z);
|
||||
data.add_vertex(sectionCenter + v, (Vec3f)v.normalized());
|
||||
}
|
||||
}
|
||||
|
||||
// triangles
|
||||
for (unsigned int i = 0; i < torusSectorCount; ++i) {
|
||||
const unsigned int ii = i * sectionSectorCount;
|
||||
const unsigned int ii_next = ((i + 1) % torusSectorCount) * sectionSectorCount;
|
||||
for (unsigned int j = 0; j < sectionSectorCount; ++j) {
|
||||
const unsigned int j_next = (j + 1) % sectionSectorCount;
|
||||
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;
|
||||
}
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -370,6 +370,10 @@ namespace GUI {
|
||||
// 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);
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -22,8 +22,8 @@ static const Slic3r::ColorRGBA HOVER_COLOR = { 0.8f, 0.2f, 0.2f, 1.0f };
|
||||
GLGizmoMeasure::GLGizmoMeasure(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
{
|
||||
m_vbo_sphere.init_from(smooth_sphere(16, 7.5f));
|
||||
m_vbo_cylinder.init_from(smooth_cylinder(16, 5.0f, 1.0f));
|
||||
m_sphere.init_from(smooth_sphere(16, 7.5f));
|
||||
m_cylinder.init_from(smooth_cylinder(16, 5.0f, 1.0f));
|
||||
}
|
||||
|
||||
bool GLGizmoMeasure::on_mouse(const wxMouseEvent &mouse_event)
|
||||
@ -188,38 +188,32 @@ void GLGizmoMeasure::on_render()
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * feature_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_vbo_sphere.set_color(HOVER_COLOR);
|
||||
m_vbo_sphere.render();
|
||||
m_sphere.set_color(HOVER_COLOR);
|
||||
m_sphere.render();
|
||||
break;
|
||||
}
|
||||
case Measure::SurfaceFeatureType::Circle:
|
||||
{
|
||||
const auto& [center, radius, n] = feature.get_circle();
|
||||
// render center
|
||||
const Transform3d feature_matrix = model_matrix * Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom);
|
||||
const Transform3d view_model_matrix = view_matrix * feature_matrix;
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * feature_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_vbo_sphere.set_color(HOVER_COLOR);
|
||||
m_vbo_sphere.render();
|
||||
const Transform3d center_matrix = model_matrix * Geometry::translation_transform(center) * Geometry::scale_transform(inv_zoom);
|
||||
const Transform3d center_view_model_matrix = view_matrix * center_matrix;
|
||||
shader->set_uniform("view_model_matrix", center_view_model_matrix);
|
||||
const Matrix3d center_view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * center_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", center_view_normal_matrix);
|
||||
m_sphere.set_color(HOVER_COLOR);
|
||||
m_sphere.render();
|
||||
|
||||
// Now draw the circle itself - let's take a funny shortcut:
|
||||
Vec3d rad = n.cross(Vec3d::UnitX());
|
||||
if (rad.squaredNorm() < 0.1)
|
||||
rad = n.cross(Vec3d::UnitY());
|
||||
rad *= radius * rad.norm();
|
||||
const int N = 32;
|
||||
m_vbo_sphere.set_color(HOVER_COLOR);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
rad = Eigen::AngleAxisd(2.0 * M_PI / N, n) * rad;
|
||||
const Transform3d feature_matrix = model_matrix * Geometry::translation_transform(center + rad) * Geometry::scale_transform(N / 100.0 * inv_zoom);
|
||||
const Transform3d view_model_matrix = view_matrix * feature_matrix;
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * feature_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_vbo_sphere.render();
|
||||
}
|
||||
m_circle.reset();
|
||||
m_circle.init_from(smooth_torus(64, 16, float(radius), 5.0f * inv_zoom));
|
||||
|
||||
const Transform3d circle_matrix = model_matrix * Geometry::translation_transform(center);
|
||||
const Transform3d circle_view_model_matrix = view_matrix * circle_matrix;
|
||||
shader->set_uniform("view_model_matrix", circle_view_model_matrix);
|
||||
const Matrix3d circle_view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * circle_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", circle_view_normal_matrix);
|
||||
m_circle.set_color(HOVER_COLOR);
|
||||
m_circle.render();
|
||||
break;
|
||||
}
|
||||
case Measure::SurfaceFeatureType::Edge:
|
||||
@ -232,23 +226,8 @@ void GLGizmoMeasure::on_render()
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * feature_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_vbo_cylinder.set_color(HOVER_COLOR);
|
||||
m_vbo_cylinder.render();
|
||||
|
||||
/*
|
||||
std::optional<Vec3d> extra_point = feature.get_extra_point();
|
||||
if (extra_point.has_value()) {
|
||||
const Vec3d pin = *extra_point;
|
||||
const Transform3d feature_matrix = Geometry::translation_transform(pin + selection.get_first_volume()->get_sla_shift_z() * Vec3d::UnitZ()) *
|
||||
Geometry::scale_transform(inv_zoom) * model_matrix;
|
||||
const Transform3d view_model_matrix = view_matrix * feature_matrix;
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * feature_matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
m_vbo_sphere.set_color(HOVER_COLOR);
|
||||
m_vbo_sphere.render();
|
||||
}
|
||||
*/
|
||||
m_cylinder.set_color(HOVER_COLOR);
|
||||
m_cylinder.render();
|
||||
break;
|
||||
}
|
||||
case Measure::SurfaceFeatureType::Plane:
|
||||
|
@ -32,8 +32,9 @@ class GLGizmoMeasure : public GLGizmoBase
|
||||
private:
|
||||
std::unique_ptr<Measure::Measuring> m_measuring;
|
||||
|
||||
GLModel m_vbo_sphere;
|
||||
GLModel m_vbo_cylinder;
|
||||
GLModel m_sphere;
|
||||
GLModel m_cylinder;
|
||||
GLModel m_circle;
|
||||
|
||||
// This holds information to decide whether recalculation is necessary:
|
||||
std::vector<Transform3d> m_volumes_matrices;
|
||||
|
Loading…
Reference in New Issue
Block a user