mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
Finished picking by color with a checksum in the alpha channel
to guard against unwanted alpha blending and / or multi sampling.
This commit is contained in:
parent
2ad3c05a65
commit
2d7f478dac
10 changed files with 89 additions and 74 deletions
|
@ -29,19 +29,21 @@ GLGizmoBase::Grabber::Grabber()
|
|||
color[0] = 1.0f;
|
||||
color[1] = 1.0f;
|
||||
color[2] = 1.0f;
|
||||
color[3] = 1.0f;
|
||||
}
|
||||
|
||||
void GLGizmoBase::Grabber::render(bool hover, float size) const
|
||||
{
|
||||
float render_color[3];
|
||||
float render_color[4];
|
||||
if (hover)
|
||||
{
|
||||
render_color[0] = 1.0f - color[0];
|
||||
render_color[1] = 1.0f - color[1];
|
||||
render_color[2] = 1.0f - color[2];
|
||||
render_color[3] = color[3];
|
||||
}
|
||||
else
|
||||
::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float));
|
||||
::memcpy((void*)render_color, (const void*)color, 4 * sizeof(float));
|
||||
|
||||
render(size, render_color, true);
|
||||
}
|
||||
|
@ -63,7 +65,7 @@ void GLGizmoBase::Grabber::render(float size, const float* render_color, bool us
|
|||
if (use_lighting)
|
||||
glsafe(::glEnable(GL_LIGHTING));
|
||||
|
||||
glsafe(::glColor3fv(render_color));
|
||||
glsafe(::glColor4fv(render_color));
|
||||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(center(0), center(1), center(2)));
|
||||
|
@ -144,9 +146,9 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, u
|
|||
, m_dragging(false)
|
||||
, m_imgui(wxGetApp().imgui())
|
||||
{
|
||||
::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 3 * sizeof(float));
|
||||
::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 3 * sizeof(float));
|
||||
::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 3 * sizeof(float));
|
||||
::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 4 * sizeof(float));
|
||||
::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 4 * sizeof(float));
|
||||
::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float));
|
||||
}
|
||||
|
||||
void GLGizmoBase::set_hover_id(int id)
|
||||
|
@ -161,7 +163,7 @@ void GLGizmoBase::set_hover_id(int id)
|
|||
void GLGizmoBase::set_highlight_color(const float* color)
|
||||
{
|
||||
if (color != nullptr)
|
||||
::memcpy((void*)m_highlight_color, (const void*)color, 3 * sizeof(float));
|
||||
::memcpy((void*)m_highlight_color, (const void*)color, 4 * sizeof(float));
|
||||
}
|
||||
|
||||
void GLGizmoBase::enable_grabber(unsigned int id)
|
||||
|
@ -210,7 +212,7 @@ void GLGizmoBase::update(const UpdateData& data)
|
|||
on_update(data);
|
||||
}
|
||||
|
||||
std::array<float, 3> GLGizmoBase::picking_color_component(unsigned int id) const
|
||||
std::array<float, 4> GLGizmoBase::picking_color_component(unsigned int id) const
|
||||
{
|
||||
static const float INV_255 = 1.0f / 255.0f;
|
||||
|
||||
|
@ -220,9 +222,12 @@ std::array<float, 3> GLGizmoBase::picking_color_component(unsigned int id) const
|
|||
id -= m_group_id;
|
||||
|
||||
// color components are encoded to match the calculation of volume_id made into GLCanvas3D::_picking_pass()
|
||||
return std::array<float, 3> { (float)((id >> 0) & 0xff) * INV_255, // red
|
||||
(float)((id >> 8) & 0xff) * INV_255, // green
|
||||
(float)((id >> 16) & 0xff) * INV_255 }; // blue
|
||||
return std::array<float, 4> {
|
||||
float((id >> 0) & 0xff) * INV_255, // red
|
||||
float((id >> 8) & 0xff) * INV_255, // green
|
||||
float((id >> 16) & 0xff) * INV_255, // blue
|
||||
float(picking_checksum_alpha_channel(id & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff))* INV_255 // checksum for validating against unwanted alpha blending and multi sampling
|
||||
};
|
||||
}
|
||||
|
||||
void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
|
||||
|
@ -247,10 +252,11 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
|
|||
{
|
||||
if (m_grabbers[i].enabled)
|
||||
{
|
||||
std::array<float, 3> color = picking_color_component(i);
|
||||
std::array<float, 4> color = picking_color_component(i);
|
||||
m_grabbers[i].color[0] = color[0];
|
||||
m_grabbers[i].color[1] = color[1];
|
||||
m_grabbers[i].color[2] = color[2];
|
||||
m_grabbers[i].color[3] = color[3];
|
||||
m_grabbers[i].render_for_picking(mean_size);
|
||||
}
|
||||
}
|
||||
|
@ -267,5 +273,20 @@ std::string GLGizmoBase::format(float value, unsigned int decimals) const
|
|||
return Slic3r::string_printf("%.*f", decimals, value);
|
||||
}
|
||||
|
||||
// Produce an alpha channel checksum for the red green blue components. The alpha channel may then be used to verify, whether the rgb components
|
||||
// were not interpolated by alpha blending or multi sampling.
|
||||
unsigned char picking_checksum_alpha_channel(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
// 8 bit hash for the color
|
||||
unsigned char b = ((((37 * red) + green) & 0x0ff) * 37 + blue) & 0x0ff;
|
||||
// Increase enthropy by a bit reversal
|
||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||
// Flip every second bit to increase the enthropy even more.
|
||||
b ^= 0x55;
|
||||
return b;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue