mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-23 06:33:57 -06:00
Tech ENABLE_GLBEGIN_GLEND_REMOVAL - Various Gizmos updates and fixes
prusa3d/PrusaSlicer@35dd03e8cb prusa3d/PrusaSlicer@bcaa0d38bd prusa3d/PrusaSlicer@2673994471 prusa3d/PrusaSlicer@0e3a3aa522 prusa3d/PrusaSlicer@08a2711034 prusa3d/PrusaSlicer@f6f95808cc prusa3d/PrusaSlicer@81edc7d752 prusa3d/PrusaSlicer@0b6e2b4aec prusa3d/PrusaSlicer@71f08841f9
This commit is contained in:
parent
f6a3421e2a
commit
7e04448b7a
23 changed files with 742 additions and 449 deletions
|
@ -105,7 +105,7 @@ bool GLGizmoFdmSupports::on_init()
|
|||
return true;
|
||||
}
|
||||
|
||||
void GLGizmoFdmSupports::render_painter_gizmo() const
|
||||
void GLGizmoFdmSupports::render_painter_gizmo()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class GLGizmoFdmSupports : public GLGizmoPainterBase
|
|||
public:
|
||||
GLGizmoFdmSupports(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
|
||||
void render_painter_gizmo() const override;
|
||||
void render_painter_gizmo() override;
|
||||
|
||||
//BBS: add edit state
|
||||
enum EditState {
|
||||
|
|
|
@ -146,7 +146,7 @@ GLGizmoMmuSegmentation::GLGizmoMmuSegmentation(GLCanvas3D& parent, const std::st
|
|||
{
|
||||
}
|
||||
|
||||
void GLGizmoMmuSegmentation::render_painter_gizmo() const
|
||||
void GLGizmoMmuSegmentation::render_painter_gizmo()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
GLGizmoMmuSegmentation(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
~GLGizmoMmuSegmentation() override = default;
|
||||
|
||||
void render_painter_gizmo() const override;
|
||||
void render_painter_gizmo() override;
|
||||
|
||||
void set_painter_gizmo_data(const Selection& selection) override;
|
||||
|
||||
|
|
|
@ -23,11 +23,6 @@ const double GLGizmoMove3D::Offset = 10.0;
|
|||
//BBS: GUI refactor: add obj manipulation
|
||||
GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, GizmoObjectManipulation* obj_manipulation)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
, m_displacement(Vec3d::Zero())
|
||||
, m_snap_step(1.0)
|
||||
, m_starting_drag_position(Vec3d::Zero())
|
||||
, m_starting_box_center(Vec3d::Zero())
|
||||
, m_starting_box_bottom_center(Vec3d::Zero())
|
||||
//BBS: GUI refactor: add obj manipulation
|
||||
, m_object_manipulation(obj_manipulation)
|
||||
{
|
||||
|
@ -137,25 +132,57 @@ void GLGizmoMove3D::on_render()
|
|||
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
|
||||
// draw grabbers
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if (m_grabbers[i].enabled) render_grabber_extension((Axis) i, box, false);
|
||||
}
|
||||
auto render_grabber_connection = [this, ¢er](unsigned int id) {
|
||||
if (m_grabbers[id].enabled) {
|
||||
if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) {
|
||||
m_grabber_connections[id].old_center = center;
|
||||
m_grabber_connections[id].model.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2);
|
||||
entity.positions.emplace_back(center.cast<float>());
|
||||
entity.positions.emplace_back(m_grabbers[id].center.cast<float>());
|
||||
|
||||
entity.normals.reserve(2);
|
||||
for (size_t j = 0; j < 2; ++j) {
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
}
|
||||
|
||||
entity.indices.reserve(2);
|
||||
entity.indices.emplace_back(0);
|
||||
entity.indices.emplace_back(1);
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_grabber_connections[id].model.init_from(init_data);
|
||||
m_grabber_connections[id].model.set_color(-1, AXES_COLOR[id]);
|
||||
}
|
||||
|
||||
// draw axes line
|
||||
// draw axes
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if (m_grabbers[i].enabled) {
|
||||
glsafe(::glColor4fv(AXES_COLOR[i].data()));
|
||||
glLineStipple(1, 0x0FFF);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
::glBegin(GL_LINES);
|
||||
::glVertex3dv(center.data());
|
||||
// use extension center
|
||||
::glVertex3dv(m_grabbers[i].center.data());
|
||||
glsafe(::glEnd());
|
||||
m_grabber_connections[id].model.render();
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
};
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
// draw axes line
|
||||
// draw axes
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
render_grabber_connection(i);
|
||||
}
|
||||
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
// draw grabbers
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if (m_grabbers[i].enabled)
|
||||
render_grabber_extension((Axis) i, box, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,15 +15,19 @@ class GLGizmoMove3D : public GLGizmoBase
|
|||
{
|
||||
static const double Offset;
|
||||
|
||||
Vec3d m_displacement;
|
||||
|
||||
double m_snap_step;
|
||||
|
||||
Vec3d m_starting_drag_position;
|
||||
Vec3d m_starting_box_center;
|
||||
Vec3d m_starting_box_bottom_center;
|
||||
Vec3d m_displacement{ Vec3d::Zero() };
|
||||
double m_snap_step{ 1.0 };
|
||||
Vec3d m_starting_drag_position{ Vec3d::Zero() };
|
||||
Vec3d m_starting_box_center{ Vec3d::Zero() };
|
||||
Vec3d m_starting_box_bottom_center{ Vec3d::Zero() };
|
||||
|
||||
GLModel m_vbo_cone;
|
||||
struct GrabberConnection
|
||||
{
|
||||
GLModel model;
|
||||
Vec3d old_center{ Vec3d::Zero() };
|
||||
};
|
||||
std::array<GrabberConnection, 3> m_grabber_connections;
|
||||
|
||||
//BBS: add size adjust related
|
||||
GizmoObjectManipulation* m_object_manipulation;
|
||||
|
|
|
@ -119,7 +119,7 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
|
|||
}
|
||||
|
||||
|
||||
void GLGizmoPainterBase::render_cursor() const
|
||||
void GLGizmoPainterBase::render_cursor()
|
||||
{
|
||||
// First check that the mouse pointer is on an object.
|
||||
const ModelObject* mo = m_c->selection_info()->model_object();
|
||||
|
@ -159,31 +159,22 @@ void GLGizmoPainterBase::render_cursor() const
|
|||
|
||||
|
||||
|
||||
void GLGizmoPainterBase::render_cursor_circle() const
|
||||
void GLGizmoPainterBase::render_cursor_circle()
|
||||
{
|
||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||
auto zoom = (float) camera.get_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
const float zoom = float(camera.get_zoom());
|
||||
const float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
Size cnv_size = m_parent.get_canvas_size();
|
||||
float cnv_half_width = 0.5f * (float) cnv_size.get_width();
|
||||
float cnv_half_height = 0.5f * (float) cnv_size.get_height();
|
||||
if ((cnv_half_width == 0.0f) || (cnv_half_height == 0.0f))
|
||||
const Size cnv_size = m_parent.get_canvas_size();
|
||||
const float cnv_half_width = 0.5f * float(cnv_size.get_width());
|
||||
const float cnv_half_height = 0.5f * float(cnv_size.get_height());
|
||||
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
|
||||
return;
|
||||
Vec2d mouse_pos(m_parent.get_local_mouse_position()(0), m_parent.get_local_mouse_position()(1));
|
||||
Vec2d center(mouse_pos(0) - cnv_half_width, cnv_half_height - mouse_pos(1));
|
||||
const Vec2d mouse_pos(m_parent.get_local_mouse_position().x(), m_parent.get_local_mouse_position().y());
|
||||
Vec2d center(mouse_pos.x() - cnv_half_width, cnv_half_height - mouse_pos.y());
|
||||
center = center * inv_zoom;
|
||||
|
||||
glsafe(::glLineWidth(1.5f));
|
||||
|
||||
// BBS
|
||||
ColorRGBA render_color = this->get_cursor_hover_color();
|
||||
if (m_button_down == Button::Left)
|
||||
render_color = this->get_cursor_sphere_left_button_color();
|
||||
else if (m_button_down == Button::Right)
|
||||
render_color = this->get_cursor_sphere_right_button_color();
|
||||
glsafe(::glColor4fv(render_color.data()));
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
|
@ -191,17 +182,46 @@ void GLGizmoPainterBase::render_cursor_circle() const
|
|||
// ensure that the circle is renderered inside the frustrum
|
||||
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
|
||||
// ensure that the overlay fits the frustrum near z plane
|
||||
double gui_scale = camera.get_gui_scale();
|
||||
const double gui_scale = camera.get_gui_scale();
|
||||
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
|
||||
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
glsafe(::glEnable(GL_LINE_STIPPLE));
|
||||
|
||||
::glBegin(GL_LINE_LOOP);
|
||||
for (double angle=0; angle<2*M_PI; angle+=M_PI/20.)
|
||||
::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle)));
|
||||
glsafe(::glEnd());
|
||||
if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - m_cursor_radius) > EPSILON) {
|
||||
m_old_center = center;
|
||||
m_old_cursor_radius = m_cursor_radius;
|
||||
m_circle.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::LineLoop;
|
||||
static const unsigned int StepsCount = 32;
|
||||
static const float StepSize = 2.0f * float(PI) / float(StepsCount);
|
||||
entity.positions.reserve(StepsCount);
|
||||
entity.normals.reserve(StepsCount);
|
||||
entity.indices.reserve(StepsCount);
|
||||
for (unsigned int i = 0; i < StepsCount; ++i) {
|
||||
const float angle = float(i * StepSize);
|
||||
entity.positions.emplace_back(center.x() + ::cos(angle) * m_cursor_radius, center.y() + ::sin(angle) * m_cursor_radius, 0.0f);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(i);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_circle.init_from(init_data);
|
||||
}
|
||||
|
||||
// BBS
|
||||
ColorRGBA render_color = this->get_cursor_hover_color();
|
||||
if (m_button_down == Button::Left)
|
||||
render_color = this->get_cursor_sphere_left_button_color();
|
||||
else if (m_button_down == Button::Right)
|
||||
render_color = this->get_cursor_sphere_right_button_color();
|
||||
|
||||
m_circle.set_color(-1, render_color);
|
||||
m_circle.render();
|
||||
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPopMatrix());
|
||||
|
|
|
@ -225,7 +225,7 @@ public:
|
|||
// from usual on_render method allows to render them before transparent
|
||||
// objects, so they can be seen inside them. The usual on_render is called
|
||||
// after all volumes (including transparent ones) are rendered.
|
||||
virtual void render_painter_gizmo() const = 0;
|
||||
virtual void render_painter_gizmo() = 0;
|
||||
|
||||
virtual const float get_cursor_radius_min() const { return CursorRadiusMin; }
|
||||
virtual const float get_cursor_radius_max() const { return CursorRadiusMax; }
|
||||
|
@ -238,8 +238,8 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void render_triangles(const Selection& selection) const;
|
||||
void render_cursor() const;
|
||||
void render_cursor_circle() const;
|
||||
void render_cursor();
|
||||
void render_cursor_circle();
|
||||
void render_cursor_sphere(const Transform3d& trafo) const;
|
||||
// BBS
|
||||
void render_cursor_height_range(const Transform3d& trafo) const;
|
||||
|
@ -300,6 +300,9 @@ protected:
|
|||
bool m_paint_on_overhangs_only = false;
|
||||
float m_highlight_by_angle_threshold_deg = 0.f;
|
||||
|
||||
GLModel m_circle;
|
||||
Vec2d m_old_center{ Vec2d::Zero() };
|
||||
float m_old_cursor_radius{ 0.0f };
|
||||
static constexpr float SmartFillAngleMin = 0.0f;
|
||||
static constexpr float SmartFillAngleMax = 90.f;
|
||||
static constexpr float SmartFillAngleStep = 1.f;
|
||||
|
|
|
@ -17,10 +17,9 @@ namespace GUI {
|
|||
|
||||
|
||||
const float GLGizmoRotate::Offset = 5.0f;
|
||||
const unsigned int GLGizmoRotate::CircleResolution = 64;
|
||||
const unsigned int GLGizmoRotate::AngleResolution = 64;
|
||||
const unsigned int GLGizmoRotate::ScaleStepsCount = 72;
|
||||
const float GLGizmoRotate::ScaleStepRad = 2.0f * (float)PI / GLGizmoRotate::ScaleStepsCount;
|
||||
const float GLGizmoRotate::ScaleStepRad = 2.0f * float(PI) / GLGizmoRotate::ScaleStepsCount;
|
||||
const unsigned int GLGizmoRotate::ScaleLongEvery = 2;
|
||||
const float GLGizmoRotate::ScaleLongTooth = 0.1f; // in percent of radius
|
||||
const unsigned int GLGizmoRotate::SnapRegionsCount = 8;
|
||||
|
@ -30,15 +29,7 @@ const float GLGizmoRotate::GrabberOffset = 0.15f; // in percent of radius
|
|||
GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
|
||||
: GLGizmoBase(parent, "", -1)
|
||||
, m_axis(axis)
|
||||
, m_angle(0.0)
|
||||
, m_center(0.0, 0.0, 0.0)
|
||||
, m_radius(0.0f)
|
||||
, m_snap_coarse_in_radius(0.0f)
|
||||
, m_snap_coarse_out_radius(0.0f)
|
||||
, m_snap_fine_in_radius(0.0f)
|
||||
, m_snap_fine_out_radius(0.0f)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other)
|
||||
: GLGizmoBase(other.m_parent, other.m_icon_filename, other.m_sprite_id)
|
||||
|
@ -56,7 +47,7 @@ GLGizmoRotate::GLGizmoRotate(const GLGizmoRotate& other)
|
|||
|
||||
void GLGizmoRotate::set_angle(double angle)
|
||||
{
|
||||
if (std::abs(angle - 2.0 * (double)PI) < EPSILON)
|
||||
if (std::abs(angle - 2.0 * double(PI)) < EPSILON)
|
||||
angle = 0.0;
|
||||
|
||||
m_angle = angle;
|
||||
|
@ -71,7 +62,7 @@ std::string GLGizmoRotate::get_tooltip() const
|
|||
case Y: { axis = "Y"; break; }
|
||||
case Z: { axis = "Z"; break; }
|
||||
}
|
||||
return (m_hover_id == 0 || m_grabbers[0].dragging) ? axis + ": " + format((float)Geometry::rad2deg(m_angle), 2) : "";
|
||||
return (m_hover_id == 0 || m_grabbers.front().dragging) ? axis + ": " + format(float(Geometry::rad2deg(m_angle)), 2) : "";
|
||||
}
|
||||
|
||||
bool GLGizmoRotate::on_init()
|
||||
|
@ -94,34 +85,31 @@ void GLGizmoRotate::on_start_dragging()
|
|||
|
||||
void GLGizmoRotate::on_update(const UpdateData& data)
|
||||
{
|
||||
Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection()));
|
||||
const Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(data.mouse_ray, m_parent.get_selection()));
|
||||
|
||||
Vec2d orig_dir = Vec2d::UnitX();
|
||||
Vec2d new_dir = mouse_pos.normalized();
|
||||
const Vec2d orig_dir = Vec2d::UnitX();
|
||||
const Vec2d new_dir = mouse_pos.normalized();
|
||||
|
||||
double theta = ::acos(std::clamp(new_dir.dot(orig_dir), -1.0, 1.0));
|
||||
if (cross2(orig_dir, new_dir) < 0.0)
|
||||
theta = 2.0 * (double)PI - theta;
|
||||
|
||||
double len = mouse_pos.norm();
|
||||
const double len = mouse_pos.norm();
|
||||
|
||||
// snap to coarse snap region
|
||||
if ((m_snap_coarse_in_radius <= len) && (len <= m_snap_coarse_out_radius))
|
||||
{
|
||||
double step = 2.0 * (double)PI / (double)SnapRegionsCount;
|
||||
theta = step * (double)std::round(theta / step);
|
||||
if (m_snap_coarse_in_radius <= len && len <= m_snap_coarse_out_radius) {
|
||||
const double step = 2.0 * double(PI) / double(SnapRegionsCount);
|
||||
theta = step * std::round(theta / step);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// snap to fine snap region (scale)
|
||||
if ((m_snap_fine_in_radius <= len) && (len <= m_snap_fine_out_radius))
|
||||
{
|
||||
double step = 2.0 * (double)PI / (double)ScaleStepsCount;
|
||||
theta = step * (double)std::round(theta / step);
|
||||
if (m_snap_fine_in_radius <= len && len <= m_snap_fine_out_radius) {
|
||||
const double step = 2.0 * double(PI) / double(ScaleStepsCount);
|
||||
theta = step * std::round(theta / step);
|
||||
}
|
||||
}
|
||||
|
||||
if (theta == 2.0 * (double)PI)
|
||||
if (theta == 2.0 * double(PI))
|
||||
theta = 0.0;
|
||||
|
||||
m_angle = theta;
|
||||
|
@ -129,13 +117,13 @@ void GLGizmoRotate::on_update(const UpdateData& data)
|
|||
|
||||
void GLGizmoRotate::on_render()
|
||||
{
|
||||
if (!m_grabbers[0].enabled)
|
||||
if (!m_grabbers.front().enabled)
|
||||
return;
|
||||
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
||||
|
||||
if (m_hover_id != 0 && !m_grabbers[0].dragging) {
|
||||
if (m_hover_id != 0 && !m_grabbers.front().dragging) {
|
||||
m_center = m_custom_center == Vec3d::Zero() ? box.center() : m_custom_center;
|
||||
m_radius = Offset + box.radius();
|
||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
||||
|
@ -144,27 +132,42 @@ void GLGizmoRotate::on_render()
|
|||
m_snap_fine_out_radius = m_radius * (1.0f + ScaleLongTooth);
|
||||
}
|
||||
|
||||
const double grabber_radius = (double)m_radius * (1.0 + (double)GrabberOffset);
|
||||
m_grabbers.front().center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
|
||||
m_grabbers.front().angles.z() = m_angle;
|
||||
m_grabbers.front().color = AXES_COLOR[m_axis];
|
||||
m_grabbers.front().hover_color = AXES_HOVER_COLOR[m_axis];
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
transform_to_local(selection);
|
||||
|
||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||
glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data()));
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
||||
render_circle();
|
||||
const float radius = Offset + m_parent.get_selection().get_bounding_box().radius();
|
||||
const bool radius_changed = std::abs(m_old_radius - radius) > EPSILON;
|
||||
m_old_radius = radius;
|
||||
|
||||
if (m_hover_id != -1) {
|
||||
render_scale();
|
||||
render_snap_radii();
|
||||
render_reference_radius();
|
||||
ColorRGBA color((m_hover_id != -1) ? m_drag_color : m_highlight_color);
|
||||
render_circle(color, radius_changed);
|
||||
if (m_hover_id != -1) {
|
||||
const bool hover_radius_changed = std::abs(m_old_hover_radius - radius) > EPSILON;
|
||||
m_old_hover_radius = radius;
|
||||
|
||||
render_scale(color, hover_radius_changed);
|
||||
render_snap_radii(color, hover_radius_changed);
|
||||
render_reference_radius(color, hover_radius_changed);
|
||||
render_angle_arc(m_highlight_color, hover_radius_changed);
|
||||
}
|
||||
|
||||
render_grabber_connection(color, radius_changed);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glColor4fv(m_highlight_color.data()));
|
||||
|
||||
if (m_hover_id != -1)
|
||||
render_angle();
|
||||
|
||||
render_grabber(box);
|
||||
render_grabber_extension(box, false);
|
||||
|
||||
|
@ -220,138 +223,223 @@ void GLGizmoRotate3D::load_rotoptimize_state()
|
|||
}
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_circle() const
|
||||
void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
::glBegin(GL_LINE_LOOP);
|
||||
for (unsigned int i = 0; i < ScaleStepsCount; ++i)
|
||||
{
|
||||
float angle = (float)i * ScaleStepRad;
|
||||
float x = ::cos(angle) * m_radius;
|
||||
float y = ::sin(angle) * m_radius;
|
||||
float z = 0.0f;
|
||||
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
|
||||
if (!m_circle.is_initialized() || radius_changed) {
|
||||
m_circle.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::LineLoop;
|
||||
entity.positions.reserve(ScaleStepsCount);
|
||||
entity.normals.reserve(ScaleStepsCount);
|
||||
entity.indices.reserve(ScaleStepsCount);
|
||||
for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
|
||||
const float angle = float(i * ScaleStepRad);
|
||||
entity.positions.emplace_back(::cos(angle) * m_radius, ::sin(angle) * m_radius, 0.0f);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(i);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_circle.init_from(init_data);
|
||||
}
|
||||
glsafe(::glEnd());
|
||||
|
||||
m_circle.set_color(-1, color);
|
||||
m_circle.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_scale() const
|
||||
void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
float out_radius_long = m_snap_fine_out_radius;
|
||||
float out_radius_short = m_radius * (1.0f + 0.5f * ScaleLongTooth);
|
||||
const float out_radius_long = m_snap_fine_out_radius;
|
||||
const float out_radius_short = m_radius * (1.0f + 0.5f * ScaleLongTooth);
|
||||
|
||||
::glBegin(GL_LINES);
|
||||
for (unsigned int i = 0; i < ScaleStepsCount; ++i)
|
||||
{
|
||||
float angle = (float)i * ScaleStepRad;
|
||||
float cosa = ::cos(angle);
|
||||
float sina = ::sin(angle);
|
||||
float in_x = cosa * m_radius;
|
||||
float in_y = sina * m_radius;
|
||||
float in_z = 0.0f;
|
||||
float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short;
|
||||
float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short;
|
||||
float out_z = 0.0f;
|
||||
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
|
||||
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
|
||||
}
|
||||
glsafe(::glEnd());
|
||||
if (!m_scale.is_initialized() || radius_changed) {
|
||||
m_scale.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2 * ScaleStepsCount);
|
||||
entity.normals.reserve(2 * ScaleStepsCount);
|
||||
entity.indices.reserve(2 * ScaleStepsCount);
|
||||
for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
|
||||
const float angle = float(i * ScaleStepRad);
|
||||
const float cosa = ::cos(angle);
|
||||
const float sina = ::sin(angle);
|
||||
const float in_x = cosa * m_radius;
|
||||
const float in_y = sina * m_radius;
|
||||
const float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short;
|
||||
const float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short;
|
||||
|
||||
entity.positions.emplace_back(in_x, in_y, 0.0f);
|
||||
entity.positions.emplace_back(out_x, out_y, 0.0f);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(i * 2 + 0);
|
||||
entity.indices.emplace_back(i * 2 + 1);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_scale.init_from(init_data);
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_snap_radii() const
|
||||
{
|
||||
float step = 2.0f * (float)PI / (float)SnapRegionsCount;
|
||||
|
||||
float in_radius = m_radius / 3.0f;
|
||||
float out_radius = 2.0f * in_radius;
|
||||
|
||||
::glBegin(GL_LINES);
|
||||
for (unsigned int i = 0; i < SnapRegionsCount; ++i)
|
||||
{
|
||||
float angle = (float)i * step;
|
||||
float cosa = ::cos(angle);
|
||||
float sina = ::sin(angle);
|
||||
float in_x = cosa * in_radius;
|
||||
float in_y = sina * in_radius;
|
||||
float in_z = 0.0f;
|
||||
float out_x = cosa * out_radius;
|
||||
float out_y = sina * out_radius;
|
||||
float out_z = 0.0f;
|
||||
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
|
||||
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
|
||||
}
|
||||
glsafe(::glEnd());
|
||||
m_scale.set_color(-1, color);
|
||||
m_scale.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_reference_radius() const
|
||||
void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
::glBegin(GL_LINES);
|
||||
::glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f);
|
||||
glsafe(::glEnd());
|
||||
const float step = 2.0f * float(PI) / float(SnapRegionsCount);
|
||||
const float in_radius = m_radius / 3.0f;
|
||||
const float out_radius = 2.0f * in_radius;
|
||||
|
||||
if (!m_snap_radii.is_initialized() || radius_changed) {
|
||||
m_snap_radii.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2 * ScaleStepsCount);
|
||||
entity.normals.reserve(2 * ScaleStepsCount);
|
||||
entity.indices.reserve(2 * ScaleStepsCount);
|
||||
for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
|
||||
const float angle = float(i * step);
|
||||
const float cosa = ::cos(angle);
|
||||
const float sina = ::sin(angle);
|
||||
const float in_x = cosa * in_radius;
|
||||
const float in_y = sina * in_radius;
|
||||
const float out_x = cosa * out_radius;
|
||||
const float out_y = sina * out_radius;
|
||||
|
||||
entity.positions.emplace_back(in_x, in_y, 0.0f);
|
||||
entity.positions.emplace_back(out_x, out_y, 0.0f);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(i * 2 + 0);
|
||||
entity.indices.emplace_back(i * 2 + 1);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_snap_radii.init_from(init_data);
|
||||
}
|
||||
|
||||
m_snap_radii.set_color(-1, color);
|
||||
m_snap_radii.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_angle() const
|
||||
void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
float step_angle = (float)m_angle / AngleResolution;
|
||||
float ex_radius = m_radius * (1.0f + GrabberOffset);
|
||||
if (!m_reference_radius.is_initialized() || radius_changed) {
|
||||
m_reference_radius.reset();
|
||||
|
||||
::glBegin(GL_LINE_STRIP);
|
||||
for (unsigned int i = 0; i <= AngleResolution; ++i)
|
||||
{
|
||||
float angle = (float)i * step_angle;
|
||||
float x = ::cos(angle) * ex_radius;
|
||||
float y = ::sin(angle) * ex_radius;
|
||||
float z = 0.0f;
|
||||
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2);
|
||||
entity.positions.emplace_back(0.0f, 0.0f, 0.0f);
|
||||
entity.positions.emplace_back(m_radius * (1.0f + GrabberOffset), 0.0f, 0.0f);
|
||||
entity.normals.reserve(2);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.reserve(2);
|
||||
entity.indices.emplace_back(0);
|
||||
entity.indices.emplace_back(1);
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_reference_radius.init_from(init_data);
|
||||
}
|
||||
glsafe(::glEnd());
|
||||
|
||||
m_reference_radius.set_color(-1, color);
|
||||
m_reference_radius.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
const float step_angle = float(m_angle) / float(AngleResolution);
|
||||
const float ex_radius = m_radius * (1.0f + GrabberOffset);
|
||||
|
||||
if (!m_angle_arc.is_initialized() || radius_changed) {
|
||||
m_angle_arc.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::LineStrip;
|
||||
entity.positions.reserve(1 + AngleResolution);
|
||||
entity.normals.reserve(1 + AngleResolution);
|
||||
entity.indices.reserve(1 + AngleResolution);
|
||||
for (unsigned int i = 0; i <= AngleResolution; ++i) {
|
||||
const float angle = float(i) * step_angle;
|
||||
entity.positions.emplace_back(::cos(angle) * ex_radius, ::sin(angle) * ex_radius, 0.0f);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.emplace_back(i);
|
||||
}
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_angle_arc.init_from(init_data);
|
||||
}
|
||||
|
||||
m_angle_arc.set_color(-1, color);
|
||||
m_angle_arc.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radius_changed)
|
||||
{
|
||||
if (!m_grabber_connection.model.is_initialized() || radius_changed || !m_grabber_connection.old_center.isApprox(m_grabbers.front().center)) {
|
||||
m_grabber_connection.model.reset();
|
||||
m_grabber_connection.old_center = m_grabbers.front().center;
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GLModel::InitializationData::Entity entity;
|
||||
entity.type = GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2);
|
||||
entity.positions.emplace_back(0.0f, 0.0f, 0.0f);
|
||||
entity.positions.emplace_back(m_grabbers.front().center.cast<float>());
|
||||
entity.normals.reserve(2);
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
entity.indices.reserve(2);
|
||||
entity.indices.emplace_back(0);
|
||||
entity.indices.emplace_back(1);
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_grabber_connection.model.init_from(init_data);
|
||||
}
|
||||
|
||||
m_grabber_connection.model.set_color(-1, color);
|
||||
m_grabber_connection.model.render();
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const
|
||||
{
|
||||
double grabber_radius = (double)m_radius * (1.0 + (double)GrabberOffset);
|
||||
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
|
||||
m_grabbers[0].angles(2) = m_angle;
|
||||
m_grabbers[0].color = AXES_COLOR[m_axis];
|
||||
m_grabbers[0].hover_color = AXES_HOVER_COLOR[m_axis];
|
||||
|
||||
glsafe(::glColor4fv((m_hover_id != -1) ? m_drag_color.data() : m_highlight_color.data()));
|
||||
|
||||
::glBegin(GL_LINES);
|
||||
::glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
::glVertex3dv(m_grabbers[0].center.data());
|
||||
glsafe(::glEnd());
|
||||
|
||||
m_grabbers[0].color = m_highlight_color;
|
||||
m_grabbers.front().color = m_highlight_color;
|
||||
render_grabbers(box);
|
||||
}
|
||||
|
||||
void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool picking) const
|
||||
void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool picking)
|
||||
{
|
||||
double size = 0.75 * GLGizmoBase::Grabber::FixedGrabberSize * GLGizmoBase::INV_ZOOM;
|
||||
//float mean_size = (float)((box.size()(0) + box.size()(1) + box.size()(2)) / 3.0);
|
||||
//double size = m_dragging ? (double)m_grabbers[0].get_dragging_half_size(mean_size) : (double)m_grabbers[0].get_half_size(mean_size);
|
||||
|
||||
ColorRGBA color = m_grabbers[0].color;
|
||||
if (!picking && m_hover_id != -1) {
|
||||
color = m_grabbers[0].hover_color;
|
||||
//color[0] = 1.0f - color[0];
|
||||
//color[1] = 1.0f - color[1];
|
||||
//color[2] = 1.0f - color[2];
|
||||
}
|
||||
ColorRGBA color = m_grabbers.front().color;
|
||||
if (!picking && m_hover_id != -1)
|
||||
color = m_grabbers.front().hover_color;
|
||||
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
const_cast<GLModel*>(&m_cone)->set_color(-1, color);
|
||||
m_cone.set_color(-1, color);
|
||||
if (!picking) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.1f);
|
||||
}
|
||||
|
||||
const Vec3d& center = m_grabbers.front().center;
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z()));
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
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, 1.5 * size));
|
||||
|
@ -359,7 +447,7 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
|
|||
m_cone.render();
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_grabbers[0].center.x(), m_grabbers[0].center.y(), m_grabbers[0].center.z()));
|
||||
glsafe(::glTranslated(center.x(), center.y(), center.z()));
|
||||
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, 1.5 * size));
|
||||
|
@ -376,7 +464,7 @@ void GLGizmoRotate::transform_to_local(const Selection& selection) const
|
|||
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);
|
||||
const Transform3d orient_matrix = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true);
|
||||
glsafe(::glMultMatrixd(orient_matrix.data()));
|
||||
}
|
||||
|
||||
|
@ -405,7 +493,7 @@ void GLGizmoRotate::transform_to_local(const Selection& selection) const
|
|||
|
||||
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const
|
||||
{
|
||||
double half_pi = 0.5 * (double)PI;
|
||||
double half_pi = 0.5 * double(PI);
|
||||
|
||||
Transform3d m = Transform3d::Identity();
|
||||
|
||||
|
@ -486,13 +574,13 @@ bool GLGizmoRotate3D::on_is_activable() const
|
|||
|
||||
void GLGizmoRotate3D::on_start_dragging()
|
||||
{
|
||||
if ((0 <= m_hover_id) && (m_hover_id < 3))
|
||||
if (0 <= m_hover_id && m_hover_id < 3)
|
||||
m_gizmos[m_hover_id].start_dragging();
|
||||
}
|
||||
|
||||
void GLGizmoRotate3D::on_stop_dragging()
|
||||
{
|
||||
if ((0 <= m_hover_id) && (m_hover_id < 3))
|
||||
if (0 <= m_hover_id && m_hover_id < 3)
|
||||
m_gizmos[m_hover_id].stop_dragging();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace GUI {
|
|||
class GLGizmoRotate : public GLGizmoBase
|
||||
{
|
||||
static const float Offset;
|
||||
static const unsigned int CircleResolution;
|
||||
static const unsigned int AngleResolution;
|
||||
static const unsigned int ScaleStepsCount;
|
||||
static const float ScaleStepRad;
|
||||
|
@ -32,18 +31,29 @@ public:
|
|||
|
||||
private:
|
||||
Axis m_axis;
|
||||
double m_angle;
|
||||
|
||||
mutable Vec3d m_custom_center{Vec3d::Zero()};
|
||||
mutable Vec3d m_center;
|
||||
mutable float m_radius;
|
||||
|
||||
mutable float m_snap_coarse_in_radius;
|
||||
mutable float m_snap_coarse_out_radius;
|
||||
mutable float m_snap_fine_in_radius;
|
||||
mutable float m_snap_fine_out_radius;
|
||||
double m_angle{ 0.0 };
|
||||
Vec3d m_custom_center{Vec3d::Zero()};
|
||||
Vec3d m_center{ Vec3d::Zero() };
|
||||
float m_radius{ 0.0f };
|
||||
float m_snap_coarse_in_radius{ 0.0f };
|
||||
float m_snap_coarse_out_radius{ 0.0f };
|
||||
float m_snap_fine_in_radius{ 0.0f };
|
||||
float m_snap_fine_out_radius{ 0.0f };
|
||||
|
||||
GLModel m_cone;
|
||||
GLModel m_circle;
|
||||
GLModel m_scale;
|
||||
GLModel m_snap_radii;
|
||||
GLModel m_reference_radius;
|
||||
GLModel m_angle_arc;
|
||||
struct GrabberConnection
|
||||
{
|
||||
GLModel model;
|
||||
Vec3d old_center{ Vec3d::Zero() };
|
||||
};
|
||||
GrabberConnection m_grabber_connection;
|
||||
float m_old_radius{ 0.0f };
|
||||
float m_old_hover_radius{ 0.0f };
|
||||
|
||||
public:
|
||||
GLGizmoRotate(GLCanvas3D& parent, Axis axis);
|
||||
|
@ -66,13 +76,14 @@ protected:
|
|||
void on_render_for_picking() override;
|
||||
|
||||
private:
|
||||
void render_circle() const;
|
||||
void render_scale() const;
|
||||
void render_snap_radii() const;
|
||||
void render_reference_radius() const;
|
||||
void render_angle() const;
|
||||
void render_circle(const ColorRGBA& color, bool radius_changed);
|
||||
void render_scale(const ColorRGBA& color, bool radius_changed);
|
||||
void render_snap_radii(const ColorRGBA& color, bool radius_changed);
|
||||
void render_reference_radius(const ColorRGBA& color, bool radius_changed);
|
||||
void render_angle_arc(const ColorRGBA& color, bool radius_changed);
|
||||
void render_grabber_connection(const ColorRGBA& color, bool radius_changed);
|
||||
void render_grabber(const BoundingBoxf3& box) const;
|
||||
void render_grabber_extension(const BoundingBoxf3& box, bool picking) const;
|
||||
void render_grabber_extension(const BoundingBoxf3& box, bool picking);
|
||||
|
||||
void transform_to_local(const Selection& selection) const;
|
||||
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
||||
|
@ -96,8 +107,7 @@ public:
|
|||
Vec3d get_rotation() const { return Vec3d(m_gizmos[X].get_angle(), m_gizmos[Y].get_angle(), m_gizmos[Z].get_angle()); }
|
||||
void set_rotation(const Vec3d& rotation) { m_gizmos[X].set_angle(rotation(0)); m_gizmos[Y].set_angle(rotation(1)); m_gizmos[Z].set_angle(rotation(2)); }
|
||||
|
||||
std::string get_tooltip() const override
|
||||
{
|
||||
std::string get_tooltip() const override {
|
||||
std::string tooltip = m_gizmos[X].get_tooltip();
|
||||
if (tooltip.empty())
|
||||
tooltip = m_gizmos[Y].get_tooltip();
|
||||
|
@ -116,38 +126,32 @@ public:
|
|||
protected:
|
||||
bool on_init() override;
|
||||
std::string on_get_name() const override;
|
||||
void on_set_state() override
|
||||
{
|
||||
void on_set_state() override {
|
||||
for (GLGizmoRotate& g : m_gizmos)
|
||||
g.set_state(m_state);
|
||||
}
|
||||
void on_set_hover_id() override
|
||||
{
|
||||
void on_set_hover_id() override {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
|
||||
}
|
||||
void on_enable_grabber(unsigned int id) override
|
||||
{
|
||||
void on_enable_grabber(unsigned int id) override {
|
||||
if (id < 3)
|
||||
m_gizmos[id].enable_grabber(0);
|
||||
}
|
||||
void on_disable_grabber(unsigned int id) override
|
||||
{
|
||||
void on_disable_grabber(unsigned int id) override {
|
||||
if (id < 3)
|
||||
m_gizmos[id].disable_grabber(0);
|
||||
}
|
||||
bool on_is_activable() const override;
|
||||
void on_start_dragging() override;
|
||||
void on_stop_dragging() override;
|
||||
void on_update(const UpdateData& data) override
|
||||
{
|
||||
void on_update(const UpdateData& data) override {
|
||||
for (GLGizmoRotate& g : m_gizmos) {
|
||||
g.update(data);
|
||||
}
|
||||
}
|
||||
void on_render() override;
|
||||
void on_render_for_picking() override
|
||||
{
|
||||
void on_render_for_picking() override {
|
||||
for (GLGizmoRotate& g : m_gizmos) {
|
||||
g.render_for_picking();
|
||||
}
|
||||
|
@ -157,10 +161,11 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
class RotoptimzeWindow {
|
||||
class RotoptimzeWindow
|
||||
{
|
||||
ImGuiWrapper *m_imgui = nullptr;
|
||||
public:
|
||||
|
||||
public:
|
||||
struct State {
|
||||
float accuracy = 1.f;
|
||||
int method_id = 0;
|
||||
|
|
|
@ -24,12 +24,16 @@ Vec3d GetIntersectionOfRayAndPlane(Vec3d ray_position, Vec3d ray_dir, Vec3d plan
|
|||
//BBS: GUI refactor: add obj manipulation
|
||||
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, GizmoObjectManipulation* obj_manipulation)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
, m_scale(Vec3d::Ones())
|
||||
, m_offset(Vec3d::Zero())
|
||||
, m_snap_step(0.05)
|
||||
//BBS: GUI refactor: add obj manipulation
|
||||
, m_object_manipulation(obj_manipulation)
|
||||
{
|
||||
m_grabber_connections[0].grabber_indices = { 0, 1 };
|
||||
m_grabber_connections[1].grabber_indices = { 2, 3 };
|
||||
m_grabber_connections[2].grabber_indices = { 4, 5 };
|
||||
m_grabber_connections[3].grabber_indices = { 6, 7 };
|
||||
m_grabber_connections[4].grabber_indices = { 7, 8 };
|
||||
m_grabber_connections[5].grabber_indices = { 8, 9 };
|
||||
m_grabber_connections[6].grabber_indices = { 9, 6 };
|
||||
}
|
||||
|
||||
std::string GLGizmoScale3D::get_tooltip() const
|
||||
|
@ -46,17 +50,17 @@ std::string GLGizmoScale3D::get_tooltip() const
|
|||
scale = 100.0f * selection.get_volume(*selection.get_volume_idxs().begin())->get_volume_scaling_factor().cast<float>();
|
||||
|
||||
if (m_hover_id == 0 || m_hover_id == 1 || m_grabbers[0].dragging || m_grabbers[1].dragging)
|
||||
return "X: " + format(scale(0), 4) + "%";
|
||||
return "X: " + format(scale.x(), 4) + "%";
|
||||
else if (m_hover_id == 2 || m_hover_id == 3 || m_grabbers[2].dragging || m_grabbers[3].dragging)
|
||||
return "Y: " + format(scale(1), 4) + "%";
|
||||
return "Y: " + format(scale.y(), 4) + "%";
|
||||
else if (m_hover_id == 4 || m_hover_id == 5 || m_grabbers[4].dragging || m_grabbers[5].dragging)
|
||||
return "Z: " + format(scale(2), 4) + "%";
|
||||
return "Z: " + format(scale.z(), 4) + "%";
|
||||
else if (m_hover_id == 6 || m_hover_id == 7 || m_hover_id == 8 || m_hover_id == 9 ||
|
||||
m_grabbers[6].dragging || m_grabbers[7].dragging || m_grabbers[8].dragging || m_grabbers[9].dragging)
|
||||
{
|
||||
std::string tooltip = "X: " + format(scale(0), 2) + "%\n";
|
||||
tooltip += "Y: " + format(scale(1), 2) + "%\n";
|
||||
tooltip += "Z: " + format(scale(2), 2) + "%";
|
||||
std::string tooltip = "X: " + format(scale.x(), 2) + "%\n";
|
||||
tooltip += "Y: " + format(scale.y(), 2) + "%\n";
|
||||
tooltip += "Z: " + format(scale.z(), 2) + "%";
|
||||
return tooltip;
|
||||
}
|
||||
else
|
||||
|
@ -71,8 +75,7 @@ void GLGizmoScale3D::enable_ununiversal_scale(bool enable)
|
|||
|
||||
bool GLGizmoScale3D::on_init()
|
||||
{
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
m_grabbers.push_back(Grabber());
|
||||
}
|
||||
|
||||
|
@ -106,8 +109,7 @@ bool GLGizmoScale3D::on_is_activable() const
|
|||
|
||||
void GLGizmoScale3D::on_start_dragging()
|
||||
{
|
||||
if (m_hover_id != -1)
|
||||
{
|
||||
if (m_hover_id != -1) {
|
||||
m_starting.drag_position = m_grabbers[m_hover_id].center;
|
||||
m_starting.plane_center = m_grabbers[4].center;
|
||||
m_starting.plane_nromal = m_grabbers[5].center - m_grabbers[4].center;
|
||||
|
@ -115,22 +117,22 @@ void GLGizmoScale3D::on_start_dragging()
|
|||
m_starting.box = (m_starting.ctrl_down && (m_hover_id < 6)) ? m_box : m_parent.get_selection().get_bounding_box();
|
||||
|
||||
const Vec3d& center = m_starting.box.center();
|
||||
m_starting.pivots[0] = m_transform * Vec3d(m_starting.box.max(0), center(1), center(2));
|
||||
m_starting.pivots[1] = m_transform * Vec3d(m_starting.box.min(0), center(1), center(2));
|
||||
m_starting.pivots[2] = m_transform * Vec3d(center(0), m_starting.box.max(1), center(2));
|
||||
m_starting.pivots[3] = m_transform * Vec3d(center(0), m_starting.box.min(1), center(2));
|
||||
m_starting.pivots[4] = m_transform * Vec3d(center(0), center(1), m_starting.box.max(2));
|
||||
m_starting.pivots[5] = m_transform * Vec3d(center(0), center(1), m_starting.box.min(2));
|
||||
m_starting.pivots[0] = m_transform * Vec3d(m_starting.box.max.x(), center.y(), center.z());
|
||||
m_starting.pivots[1] = m_transform * Vec3d(m_starting.box.min.x(), center.y(), center.z());
|
||||
m_starting.pivots[2] = m_transform * Vec3d(center.x(), m_starting.box.max.y(), center.z());
|
||||
m_starting.pivots[3] = m_transform * Vec3d(center.x(), m_starting.box.min.y(), center.z());
|
||||
m_starting.pivots[4] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.max.z());
|
||||
m_starting.pivots[5] = m_transform * Vec3d(center.x(), center.y(), m_starting.box.min.z());
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::on_update(const UpdateData& data)
|
||||
{
|
||||
if ((m_hover_id == 0) || (m_hover_id == 1))
|
||||
if (m_hover_id == 0 || m_hover_id == 1)
|
||||
do_scale_along_axis(X, data);
|
||||
else if ((m_hover_id == 2) || (m_hover_id == 3))
|
||||
else if (m_hover_id == 2 || m_hover_id == 3)
|
||||
do_scale_along_axis(Y, data);
|
||||
else if ((m_hover_id == 4) || (m_hover_id == 5))
|
||||
else if (m_hover_id == 4 || m_hover_id == 5)
|
||||
do_scale_along_axis(Z, data);
|
||||
else if (m_hover_id >= 6)
|
||||
do_scale_uniform(data);
|
||||
|
@ -190,24 +192,24 @@ void GLGizmoScale3D::on_render()
|
|||
bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
|
||||
|
||||
// x axis
|
||||
m_grabbers[0].center = m_transform * Vec3d(m_box.min(0), center(1), m_box.min(2));
|
||||
m_grabbers[1].center = m_transform * Vec3d(m_box.max(0), center(1), m_box.min(2));
|
||||
m_grabbers[0].center = m_transform * Vec3d(m_box.min.x(), center.y(), m_box.min.z());
|
||||
m_grabbers[1].center = m_transform * Vec3d(m_box.max.x(), center.y(), m_box.min.z());
|
||||
|
||||
// y axis
|
||||
m_grabbers[2].center = m_transform * Vec3d(center(0), m_box.min(1), m_box.min(2));
|
||||
m_grabbers[3].center = m_transform * Vec3d(center(0), m_box.max(1), m_box.min(2));
|
||||
m_grabbers[2].center = m_transform * Vec3d(center.x(), m_box.min.y(), m_box.min.z());
|
||||
m_grabbers[3].center = m_transform * Vec3d(center.x(), m_box.max.y(), m_box.min.z());
|
||||
|
||||
// z axis do not show 4
|
||||
m_grabbers[4].center = m_transform * Vec3d(center(0), center(1), m_box.min(2));
|
||||
m_grabbers[4].center = m_transform * Vec3d(center.x(), center.y(), m_box.min.z());
|
||||
m_grabbers[4].enabled = false;
|
||||
|
||||
m_grabbers[5].center = m_transform * Vec3d(center(0), center(1), m_box.max(2));
|
||||
m_grabbers[5].center = m_transform * Vec3d(center.x(), center.y(), m_box.max.z());
|
||||
|
||||
// uniform
|
||||
m_grabbers[6].center = m_transform * Vec3d(m_box.min(0), m_box.min(1), m_box.min(2));
|
||||
m_grabbers[7].center = m_transform * Vec3d(m_box.max(0), m_box.min(1), m_box.min(2));
|
||||
m_grabbers[8].center = m_transform * Vec3d(m_box.max(0), m_box.max(1), m_box.min(2));
|
||||
m_grabbers[9].center = m_transform * Vec3d(m_box.min(0), m_box.max(1), m_box.min(2));
|
||||
m_grabbers[6].center = m_transform * Vec3d(m_box.min.x(), m_box.min.y(), m_box.min.z());
|
||||
m_grabbers[7].center = m_transform * Vec3d(m_box.max.x(), m_box.min.y(), m_box.min.z());
|
||||
m_grabbers[8].center = m_transform * Vec3d(m_box.max.x(), m_box.max.y(), m_box.min.z());
|
||||
m_grabbers[9].center = m_transform * Vec3d(m_box.min.x(), m_box.max.y(), m_box.min.z());
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
m_grabbers[i].color = AXES_COLOR[i/2];
|
||||
|
@ -228,26 +230,23 @@ void GLGizmoScale3D::on_render()
|
|||
|
||||
const BoundingBoxf3& selection_box = selection.get_bounding_box();
|
||||
|
||||
float grabber_mean_size = (float)((selection_box.size()(0) + selection_box.size()(1) + selection_box.size()(2)) / 3.0);
|
||||
float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
|
||||
|
||||
//draw connections
|
||||
|
||||
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
||||
//if (single_instance || single_volume) {
|
||||
|
||||
if (m_grabbers[4].enabled && m_grabbers[5].enabled) {
|
||||
glsafe(::glColor4fv(m_grabbers[4].color.data()));
|
||||
render_grabbers_connection(4, 5);
|
||||
//draw connections
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
||||
//if (single_instance || single_volume) {
|
||||
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
||||
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
||||
render_grabbers_connection(6, 7, m_grabbers[2].color);
|
||||
render_grabbers_connection(7, 8, m_grabbers[2].color);
|
||||
render_grabbers_connection(8, 9, m_grabbers[0].color);
|
||||
render_grabbers_connection(9, 6, m_grabbers[0].color);
|
||||
shader->stop_using();
|
||||
}
|
||||
|
||||
glsafe(::glColor4fv(m_grabbers[2].color.data()));
|
||||
render_grabbers_connection(6, 7);
|
||||
render_grabbers_connection(8, 9);
|
||||
|
||||
glsafe(::glColor4fv(m_grabbers[0].color.data()));
|
||||
render_grabbers_connection(7, 8);
|
||||
render_grabbers_connection(9, 6);
|
||||
|
||||
// draw grabbers
|
||||
render_grabbers(grabber_mean_size);
|
||||
}
|
||||
|
@ -258,19 +257,52 @@ void GLGizmoScale3D::on_render_for_picking()
|
|||
render_grabbers_for_picking(m_parent.get_selection().get_bounding_box());
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2) const
|
||||
void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color)
|
||||
{
|
||||
unsigned int grabbers_count = (unsigned int)m_grabbers.size();
|
||||
if ((id_1 < grabbers_count) && (id_2 < grabbers_count))
|
||||
{
|
||||
glLineStipple(1, 0x0FFF);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
::glBegin(GL_LINES);
|
||||
::glVertex3dv(m_grabbers[id_1].center.data());
|
||||
::glVertex3dv(m_grabbers[id_2].center.data());
|
||||
glsafe(::glEnd());
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
auto grabber_connection = [this](unsigned int id_1, unsigned int id_2) {
|
||||
for (int i = 0; i < int(m_grabber_connections.size()); ++i) {
|
||||
if (m_grabber_connections[i].grabber_indices.first == id_1 && m_grabber_connections[i].grabber_indices.second == id_2)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
int id = grabber_connection(id_1, id_2);
|
||||
if (id == -1)
|
||||
return;
|
||||
|
||||
if (!m_grabber_connections[id].model.is_initialized() ||
|
||||
!m_grabber_connections[id].old_v1.isApprox(m_grabbers[id_1].center) ||
|
||||
!m_grabber_connections[id].old_v2.isApprox(m_grabbers[id_2].center)) {
|
||||
m_grabber_connections[id].old_v1 = m_grabbers[id_1].center;
|
||||
m_grabber_connections[id].old_v2 = m_grabbers[id_2].center;
|
||||
m_grabber_connections[id].model.reset();
|
||||
|
||||
GLModel::InitializationData init_data;
|
||||
GUI::GLModel::InitializationData::Entity entity;
|
||||
entity.type = GUI::GLModel::PrimitiveType::Lines;
|
||||
entity.positions.reserve(2);
|
||||
entity.positions.emplace_back(m_grabbers[id_1].center.cast<float>());
|
||||
entity.positions.emplace_back(m_grabbers[id_2].center.cast<float>());
|
||||
|
||||
entity.normals.reserve(2);
|
||||
for (size_t j = 0; j < 2; ++j) {
|
||||
entity.normals.emplace_back(Vec3f::UnitZ());
|
||||
}
|
||||
|
||||
entity.indices.reserve(2);
|
||||
entity.indices.emplace_back(0);
|
||||
entity.indices.emplace_back(1);
|
||||
|
||||
init_data.entities.emplace_back(entity);
|
||||
m_grabber_connections[id].model.init_from(init_data);
|
||||
}
|
||||
|
||||
m_grabber_connections[id].model.set_color(-1, color);
|
||||
glLineStipple(1, 0x0FFF);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
m_grabber_connections[id].model.render();
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
|
||||
//BBS: add input window for move
|
||||
|
@ -283,11 +315,9 @@ void GLGizmoScale3D::on_render_input_window(float x, float y, float bottom_limit
|
|||
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
||||
{
|
||||
double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0)
|
||||
{
|
||||
if (ratio > 0.0) {
|
||||
m_scale(axis) = m_starting.scale(axis) * ratio;
|
||||
if (m_starting.ctrl_down)
|
||||
{
|
||||
if (m_starting.ctrl_down) {
|
||||
double local_offset = 0.5 * (m_scale(axis) - m_starting.scale(axis)) * m_starting.box.size()(axis);
|
||||
if (m_hover_id == 2 * axis)
|
||||
local_offset *= -1.0;
|
||||
|
@ -311,8 +341,7 @@ void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
|||
void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
|
||||
{
|
||||
double ratio = calc_ratio(data);
|
||||
if (ratio > 0.0)
|
||||
{
|
||||
if (ratio > 0.0) {
|
||||
m_scale = m_starting.scale * ratio;
|
||||
m_offset = Vec3d::Zero();
|
||||
}
|
||||
|
@ -322,11 +351,11 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
|||
{
|
||||
double ratio = 0.0;
|
||||
|
||||
Vec3d pivot = (m_starting.ctrl_down && (m_hover_id < 6)) ? m_starting.pivots[m_hover_id] : m_starting.plane_center;
|
||||
Vec3d pivot = (m_starting.ctrl_down && m_hover_id < 6) ? m_starting.pivots[m_hover_id] : m_starting.plane_center;
|
||||
|
||||
Vec3d starting_vec = m_starting.drag_position - pivot;
|
||||
double len_starting_vec = starting_vec.norm();
|
||||
if (len_starting_vec != 0.0)
|
||||
{
|
||||
if (len_starting_vec != 0.0) {
|
||||
Vec3d mouse_dir = data.mouse_ray.unit_vector();
|
||||
Vec3d plane_normal = m_starting.plane_nromal;
|
||||
if (m_hover_id == 5) {
|
||||
|
|
|
@ -32,10 +32,19 @@ class GLGizmoScale3D : public GLGizmoBase
|
|||
mutable Transform3d m_transform;
|
||||
// Transforms grabbers offsets to the proper reference system (world for instances, instance for volumes)
|
||||
mutable Transform3d m_offsets_transform;
|
||||
Vec3d m_scale;
|
||||
Vec3d m_offset;
|
||||
double m_snap_step;
|
||||
Vec3d m_scale{ Vec3d::Ones() };
|
||||
Vec3d m_offset{ Vec3d::Zero() };
|
||||
double m_snap_step{ 0.05 };
|
||||
StartingData m_starting;
|
||||
|
||||
struct GrabberConnection
|
||||
{
|
||||
GLModel model;
|
||||
std::pair<unsigned int, unsigned int> grabber_indices;
|
||||
Vec3d old_v1{ Vec3d::Zero() };
|
||||
Vec3d old_v2{ Vec3d::Zero() };
|
||||
};
|
||||
std::array<GrabberConnection, 7> m_grabber_connections;
|
||||
|
||||
//BBS: add size adjust related
|
||||
GizmoObjectManipulation* m_object_manipulation;
|
||||
|
@ -68,7 +77,7 @@ protected:
|
|||
virtual void on_render_input_window(float x, float y, float bottom_limit);
|
||||
|
||||
private:
|
||||
void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const;
|
||||
void render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color);
|
||||
|
||||
void do_scale_along_axis(Axis axis, const UpdateData& data);
|
||||
void do_scale_uniform(const UpdateData& data);
|
||||
|
|
|
@ -62,7 +62,7 @@ std::string GLGizmoSeam::on_get_name() const
|
|||
|
||||
|
||||
|
||||
void GLGizmoSeam::render_painter_gizmo() const
|
||||
void GLGizmoSeam::render_painter_gizmo()
|
||||
{
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class GLGizmoSeam : public GLGizmoPainterBase
|
|||
public:
|
||||
GLGizmoSeam(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
|
||||
void render_painter_gizmo() const override;
|
||||
void render_painter_gizmo() override;
|
||||
|
||||
//BBS
|
||||
bool on_key_down_select_tool_type(int keyCode);
|
||||
|
|
|
@ -692,7 +692,7 @@ void GLGizmosManager::render_current_gizmo() const
|
|||
m_gizmos[m_current]->render();
|
||||
}
|
||||
|
||||
void GLGizmosManager::render_painter_gizmo() const
|
||||
void GLGizmosManager::render_painter_gizmo()
|
||||
{
|
||||
// This function shall only be called when current gizmo is
|
||||
// derived from GLGizmoPainterBase.
|
||||
|
|
|
@ -31,16 +31,24 @@ class CommonGizmosDataPool;
|
|||
class GizmoObjectManipulation;
|
||||
class Rect
|
||||
{
|
||||
float m_left;
|
||||
float m_top;
|
||||
float m_right;
|
||||
float m_bottom;
|
||||
float m_left{ 0.0f };
|
||||
float m_top{ 0.0f };
|
||||
float m_right{ 0.0f };
|
||||
float m_bottom{ 0.0f };
|
||||
|
||||
public:
|
||||
Rect() : m_left(0.0f) , m_top(0.0f) , m_right(0.0f) , m_bottom(0.0f) {}
|
||||
|
||||
Rect() = default;
|
||||
Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {}
|
||||
|
||||
bool operator == (const Rect& other) {
|
||||
if (std::abs(m_left - other.m_left) > EPSILON) return false;
|
||||
if (std::abs(m_top - other.m_top) > EPSILON) return false;
|
||||
if (std::abs(m_right - other.m_right) > EPSILON) return false;
|
||||
if (std::abs(m_bottom - other.m_bottom) > EPSILON) return false;
|
||||
return true;
|
||||
}
|
||||
bool operator != (const Rect& other) { return !operator==(other); }
|
||||
|
||||
float get_left() const { return m_left; }
|
||||
void set_left(float left) { m_left = left; }
|
||||
|
||||
|
@ -287,7 +295,7 @@ public:
|
|||
void on_change_color_mode(bool is_dark);
|
||||
void render_current_gizmo() const;
|
||||
void render_current_gizmo_for_picking_pass() const;
|
||||
void render_painter_gizmo() const;
|
||||
void render_painter_gizmo();
|
||||
void render_painter_assemble_view() const;
|
||||
|
||||
void render_overlay();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue