Merge remote-tracking branch 'origin/dev' into feature_arrange_with_libnest2d
This commit is contained in:
commit
bef19fe6da
15 changed files with 517 additions and 146 deletions
|
@ -153,16 +153,15 @@ sub new {
|
||||||
};
|
};
|
||||||
|
|
||||||
# callback to react to gizmo rotate
|
# callback to react to gizmo rotate
|
||||||
# omitting last three parameters means rotation around Z
|
|
||||||
# otherwise they are the components of the rotation axis vector
|
|
||||||
my $on_gizmo_rotate = sub {
|
my $on_gizmo_rotate = sub {
|
||||||
my ($angle, $axis_x, $axis_y, $axis_z) = @_;
|
my ($angle) = @_;
|
||||||
if (!defined $axis_x) {
|
|
||||||
$self->rotate(rad2deg($angle), Z, 'absolute');
|
$self->rotate(rad2deg($angle), Z, 'absolute');
|
||||||
}
|
};
|
||||||
else {
|
|
||||||
|
# callback to react to gizmo flatten
|
||||||
|
my $on_gizmo_flatten = sub {
|
||||||
|
my ($angle, $axis_x, $axis_y, $axis_z) = @_;
|
||||||
$self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0;
|
$self->rotate(rad2deg($angle), undef, 'absolute', $axis_x, $axis_y, $axis_z) if $angle != 0;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# callback to update object's geometry info while using gizmos
|
# callback to update object's geometry info while using gizmos
|
||||||
|
@ -263,6 +262,7 @@ sub new {
|
||||||
Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons);
|
Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons);
|
||||||
Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly);
|
Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly);
|
||||||
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate);
|
Slic3r::GUI::_3DScene::register_on_gizmo_rotate_callback($self->{canvas3D}, $on_gizmo_rotate);
|
||||||
|
Slic3r::GUI::_3DScene::register_on_gizmo_flatten_callback($self->{canvas3D}, $on_gizmo_flatten);
|
||||||
Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info);
|
Slic3r::GUI::_3DScene::register_on_update_geometry_info_callback($self->{canvas3D}, $on_update_geometry_info);
|
||||||
Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add);
|
Slic3r::GUI::_3DScene::register_action_add_callback($self->{canvas3D}, $on_action_add);
|
||||||
Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete);
|
Slic3r::GUI::_3DScene::register_action_delete_callback($self->{canvas3D}, $on_action_delete);
|
||||||
|
@ -879,6 +879,15 @@ sub load_files {
|
||||||
$model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES;
|
$model->convert_multipart_object(scalar(@$nozzle_dmrs)) if $dialog->ShowModal() == wxID_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# objects imported from 3mf require a call to center_around_origin to have gizmos working properly and this call
|
||||||
|
# need to be done after looks_like_multipart_object detection
|
||||||
|
if ($input_file =~ /.3[mM][fF]$/)
|
||||||
|
{
|
||||||
|
foreach my $model_object (@{$model->objects}) {
|
||||||
|
$model_object->center_around_origin; # also aligns object to Z = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($one_by_one) {
|
if ($one_by_one) {
|
||||||
push @obj_idx, $self->load_model_objects(@{$model->objects});
|
push @obj_idx, $self->load_model_objects(@{$model->objects});
|
||||||
} else {
|
} else {
|
||||||
|
|
BIN
resources/icons/overlay/move_hover.png
Normal file
BIN
resources/icons/overlay/move_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/icons/overlay/move_off.png
Normal file
BIN
resources/icons/overlay/move_off.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/icons/overlay/move_on.png
Normal file
BIN
resources/icons/overlay/move_on.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
|
@ -601,8 +601,6 @@ namespace Slic3r {
|
||||||
|
|
||||||
if (!_generate_volumes(*object.second, obj_geometry->second, *volumes_ptr))
|
if (!_generate_volumes(*object.second, obj_geometry->second, *volumes_ptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
object.second->center_around_origin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixes the min z of the model if negative
|
// fixes the min z of the model if negative
|
||||||
|
|
|
@ -301,7 +301,7 @@ namespace Slic3r {
|
||||||
if (((_mode == Normal) && (gcode_line == Normal_First_M73_Output_Placeholder_Tag)) ||
|
if (((_mode == Normal) && (gcode_line == Normal_First_M73_Output_Placeholder_Tag)) ||
|
||||||
((_mode == Silent) && (gcode_line == Silent_First_M73_Output_Placeholder_Tag)))
|
((_mode == Silent) && (gcode_line == Silent_First_M73_Output_Placeholder_Tag)))
|
||||||
{
|
{
|
||||||
sprintf(time_line, time_mask.c_str(), std::to_string(0), _get_time_minutes(_time).c_str());
|
sprintf(time_line, time_mask.c_str(), "0", _get_time_minutes(_time).c_str());
|
||||||
gcode_line = time_line;
|
gcode_line = time_line;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -313,6 +313,14 @@ void GLVolume::set_select_group_id(const std::string& select_by)
|
||||||
select_group_id = composite_id;
|
select_group_id = composite_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLVolume::set_drag_group_id(const std::string& drag_by)
|
||||||
|
{
|
||||||
|
if (drag_by == "object")
|
||||||
|
drag_group_id = object_idx() * 1000;
|
||||||
|
else if (drag_by == "instance")
|
||||||
|
drag_group_id = object_idx() * 1000 + instance_idx();
|
||||||
|
}
|
||||||
|
|
||||||
const Transform3f& GLVolume::world_matrix() const
|
const Transform3f& GLVolume::world_matrix() const
|
||||||
{
|
{
|
||||||
if (m_world_matrix_dirty)
|
if (m_world_matrix_dirty)
|
||||||
|
@ -666,11 +674,7 @@ std::vector<int> GLVolumeCollection::load_object(
|
||||||
v.indexed_vertex_array.finalize_geometry(use_VBOs);
|
v.indexed_vertex_array.finalize_geometry(use_VBOs);
|
||||||
v.composite_id = obj_idx * 1000000 + volume_idx * 1000 + instance_idx;
|
v.composite_id = obj_idx * 1000000 + volume_idx * 1000 + instance_idx;
|
||||||
v.set_select_group_id(select_by);
|
v.set_select_group_id(select_by);
|
||||||
if (drag_by == "object")
|
v.set_drag_group_id(drag_by);
|
||||||
v.drag_group_id = obj_idx * 1000;
|
|
||||||
else if (drag_by == "instance")
|
|
||||||
v.drag_group_id = obj_idx * 1000 + instance_idx;
|
|
||||||
|
|
||||||
if (!model_volume->modifier)
|
if (!model_volume->modifier)
|
||||||
{
|
{
|
||||||
v.set_convex_hull(model_volume->get_convex_hull());
|
v.set_convex_hull(model_volume->get_convex_hull());
|
||||||
|
@ -963,6 +967,15 @@ void GLVolumeCollection::set_select_by(const std::string& select_by)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLVolumeCollection::set_drag_by(const std::string& drag_by)
|
||||||
|
{
|
||||||
|
for (GLVolume *vol : this->volumes)
|
||||||
|
{
|
||||||
|
if (vol != nullptr)
|
||||||
|
vol->set_drag_group_id(drag_by);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) const
|
std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) const
|
||||||
{
|
{
|
||||||
// Collect layer top positions of all volumes.
|
// Collect layer top positions of all volumes.
|
||||||
|
@ -2044,6 +2057,11 @@ void _3DScene::register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callb
|
||||||
s_canvas_mgr.register_on_gizmo_rotate_callback(canvas, callback);
|
s_canvas_mgr.register_on_gizmo_rotate_callback(canvas, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _3DScene::register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback)
|
||||||
|
{
|
||||||
|
s_canvas_mgr.register_on_gizmo_flatten_callback(canvas, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void _3DScene::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
|
void _3DScene::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
|
||||||
{
|
{
|
||||||
s_canvas_mgr.register_on_update_geometry_info_callback(canvas, callback);
|
s_canvas_mgr.register_on_update_geometry_info_callback(canvas, callback);
|
||||||
|
|
|
@ -338,6 +338,7 @@ public:
|
||||||
void set_convex_hull(const TriangleMesh& convex_hull);
|
void set_convex_hull(const TriangleMesh& convex_hull);
|
||||||
|
|
||||||
void set_select_group_id(const std::string& select_by);
|
void set_select_group_id(const std::string& select_by);
|
||||||
|
void set_drag_group_id(const std::string& drag_by);
|
||||||
|
|
||||||
int object_idx() const { return this->composite_id / 1000000; }
|
int object_idx() const { return this->composite_id / 1000000; }
|
||||||
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
|
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
|
||||||
|
@ -449,6 +450,7 @@ public:
|
||||||
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
void update_colors_by_extruder(const DynamicPrintConfig* config);
|
||||||
|
|
||||||
void set_select_by(const std::string& select_by);
|
void set_select_by(const std::string& select_by);
|
||||||
|
void set_drag_by(const std::string& drag_by);
|
||||||
|
|
||||||
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
|
||||||
std::vector<double> get_current_print_zs(bool active_only) const;
|
std::vector<double> get_current_print_zs(bool active_only) const;
|
||||||
|
@ -556,6 +558,7 @@ public:
|
||||||
static void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
|
static void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
|
||||||
static void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
static void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
||||||
static void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
|
static void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
static void register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback);
|
||||||
static void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
|
static void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
|
||||||
static void register_action_add_callback(wxGLCanvas* canvas, void* callback);
|
static void register_action_add_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
|
|
@ -1123,7 +1123,6 @@ const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayTexturesScale;
|
||||||
GLCanvas3D::Gizmos::Gizmos()
|
GLCanvas3D::Gizmos::Gizmos()
|
||||||
: m_enabled(false)
|
: m_enabled(false)
|
||||||
, m_current(Undefined)
|
, m_current(Undefined)
|
||||||
, m_dragging(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,13 +1133,35 @@ GLCanvas3D::Gizmos::~Gizmos()
|
||||||
|
|
||||||
bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
|
bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
|
||||||
{
|
{
|
||||||
GLGizmoBase* gizmo = new GLGizmoScale3D(parent);
|
GLGizmoBase* gizmo = new GLGizmoMove3D(parent);
|
||||||
if (gizmo == nullptr)
|
if (gizmo == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!gizmo->init())
|
if (!gizmo->init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// temporary disable z grabber
|
||||||
|
gizmo->disable_grabber(2);
|
||||||
|
|
||||||
|
m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
|
||||||
|
|
||||||
|
gizmo = new GLGizmoScale3D(parent);
|
||||||
|
if (gizmo == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!gizmo->init())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// temporary disable x grabbers
|
||||||
|
gizmo->disable_grabber(0);
|
||||||
|
gizmo->disable_grabber(1);
|
||||||
|
// temporary disable y grabbers
|
||||||
|
gizmo->disable_grabber(2);
|
||||||
|
gizmo->disable_grabber(3);
|
||||||
|
// temporary disable z grabbers
|
||||||
|
gizmo->disable_grabber(4);
|
||||||
|
gizmo->disable_grabber(5);
|
||||||
|
|
||||||
m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
|
m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
|
||||||
|
|
||||||
gizmo = new GLGizmoRotate3D(parent);
|
gizmo = new GLGizmoRotate3D(parent);
|
||||||
|
@ -1156,6 +1177,10 @@ bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// temporary disable x and y grabbers
|
||||||
|
gizmo->disable_grabber(0);
|
||||||
|
gizmo->disable_grabber(1);
|
||||||
|
|
||||||
m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
|
m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
|
||||||
|
|
||||||
gizmo = new GLGizmoFlatten(parent);
|
gizmo = new GLGizmoFlatten(parent);
|
||||||
|
@ -1336,12 +1361,12 @@ bool GLCanvas3D::Gizmos::is_running() const
|
||||||
|
|
||||||
bool GLCanvas3D::Gizmos::is_dragging() const
|
bool GLCanvas3D::Gizmos::is_dragging() const
|
||||||
{
|
{
|
||||||
return m_dragging;
|
GLGizmoBase* curr = _get_current();
|
||||||
|
return (curr != nullptr) ? curr->is_dragging() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::Gizmos::start_dragging(const BoundingBoxf3& box)
|
void GLCanvas3D::Gizmos::start_dragging(const BoundingBoxf3& box)
|
||||||
{
|
{
|
||||||
m_dragging = true;
|
|
||||||
GLGizmoBase* curr = _get_current();
|
GLGizmoBase* curr = _get_current();
|
||||||
if (curr != nullptr)
|
if (curr != nullptr)
|
||||||
curr->start_dragging(box);
|
curr->start_dragging(box);
|
||||||
|
@ -1349,12 +1374,30 @@ void GLCanvas3D::Gizmos::start_dragging(const BoundingBoxf3& box)
|
||||||
|
|
||||||
void GLCanvas3D::Gizmos::stop_dragging()
|
void GLCanvas3D::Gizmos::stop_dragging()
|
||||||
{
|
{
|
||||||
m_dragging = false;
|
|
||||||
GLGizmoBase* curr = _get_current();
|
GLGizmoBase* curr = _get_current();
|
||||||
if (curr != nullptr)
|
if (curr != nullptr)
|
||||||
curr->stop_dragging();
|
curr->stop_dragging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3d GLCanvas3D::Gizmos::get_position() const
|
||||||
|
{
|
||||||
|
if (!m_enabled)
|
||||||
|
return Vec3d::Zero();
|
||||||
|
|
||||||
|
GizmosMap::const_iterator it = m_gizmos.find(Move);
|
||||||
|
return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoMove3D*>(it->second)->get_position() : Vec3d::Zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLCanvas3D::Gizmos::set_position(const Vec3d& position)
|
||||||
|
{
|
||||||
|
if (!m_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GizmosMap::const_iterator it = m_gizmos.find(Move);
|
||||||
|
if (it != m_gizmos.end())
|
||||||
|
reinterpret_cast<GLGizmoMove3D*>(it->second)->set_position(position);
|
||||||
|
}
|
||||||
|
|
||||||
float GLCanvas3D::Gizmos::get_scale() const
|
float GLCanvas3D::Gizmos::get_scale() const
|
||||||
{
|
{
|
||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
|
@ -2143,6 +2186,7 @@ void GLCanvas3D::set_select_by(const std::string& value)
|
||||||
void GLCanvas3D::set_drag_by(const std::string& value)
|
void GLCanvas3D::set_drag_by(const std::string& value)
|
||||||
{
|
{
|
||||||
m_drag_by = value;
|
m_drag_by = value;
|
||||||
|
m_volumes.set_drag_by(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& GLCanvas3D::get_select_by() const
|
const std::string& GLCanvas3D::get_select_by() const
|
||||||
|
@ -2150,6 +2194,11 @@ const std::string& GLCanvas3D::get_select_by() const
|
||||||
return m_select_by;
|
return m_select_by;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& GLCanvas3D::get_drag_by() const
|
||||||
|
{
|
||||||
|
return m_drag_by;
|
||||||
|
}
|
||||||
|
|
||||||
float GLCanvas3D::get_camera_zoom() const
|
float GLCanvas3D::get_camera_zoom() const
|
||||||
{
|
{
|
||||||
return m_camera.zoom;
|
return m_camera.zoom;
|
||||||
|
@ -2326,6 +2375,7 @@ void GLCanvas3D::update_gizmos_data()
|
||||||
ModelInstance* model_instance = model_object->instances[0];
|
ModelInstance* model_instance = model_object->instances[0];
|
||||||
if (model_instance != nullptr)
|
if (model_instance != nullptr)
|
||||||
{
|
{
|
||||||
|
m_gizmos.set_position(Vec3d(model_instance->offset(0), model_instance->offset(1), 0.0));
|
||||||
m_gizmos.set_scale(model_instance->scaling_factor);
|
m_gizmos.set_scale(model_instance->scaling_factor);
|
||||||
m_gizmos.set_angle_z(model_instance->rotation);
|
m_gizmos.set_angle_z(model_instance->rotation);
|
||||||
m_gizmos.set_flattening_data(model_object);
|
m_gizmos.set_flattening_data(model_object);
|
||||||
|
@ -2334,6 +2384,7 @@ void GLCanvas3D::update_gizmos_data()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_gizmos.set_position(Vec3d::Zero());
|
||||||
m_gizmos.set_scale(1.0f);
|
m_gizmos.set_scale(1.0f);
|
||||||
m_gizmos.set_angle_z(0.0f);
|
m_gizmos.set_angle_z(0.0f);
|
||||||
m_gizmos.set_flattening_data(nullptr);
|
m_gizmos.set_flattening_data(nullptr);
|
||||||
|
@ -2699,6 +2750,12 @@ void GLCanvas3D::register_on_gizmo_rotate_callback(void* callback)
|
||||||
m_on_gizmo_rotate_callback.register_callback(callback);
|
m_on_gizmo_rotate_callback.register_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas3D::register_on_gizmo_flatten_callback(void* callback)
|
||||||
|
{
|
||||||
|
if (callback != nullptr)
|
||||||
|
m_on_gizmo_flatten_callback.register_callback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::register_on_update_geometry_info_callback(void* callback)
|
void GLCanvas3D::register_on_update_geometry_info_callback(void* callback)
|
||||||
{
|
{
|
||||||
if (callback != nullptr)
|
if (callback != nullptr)
|
||||||
|
@ -3016,7 +3073,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
if (normal(0) != 0.0 || normal(1) != 0.0 || normal(2) != 0.0) {
|
if (normal(0) != 0.0 || normal(1) != 0.0 || normal(2) != 0.0) {
|
||||||
Vec3d axis = normal(2) > 0.999 ? Vec3d::UnitX() : normal.cross(-Vec3d::UnitZ()).normalized();
|
Vec3d axis = normal(2) > 0.999 ? Vec3d::UnitX() : normal.cross(-Vec3d::UnitZ()).normalized();
|
||||||
float angle = acos(clamp(-1.0, 1.0, -normal(2)));
|
float angle = acos(clamp(-1.0, 1.0, -normal(2)));
|
||||||
m_on_gizmo_rotate_callback.call(angle, (float)axis(0), (float)axis(1), (float)axis(2));
|
m_on_gizmo_flatten_callback.call(angle, (float)axis(0), (float)axis(1), (float)axis(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3175,6 +3232,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
|
|
||||||
switch (m_gizmos.get_current_type())
|
switch (m_gizmos.get_current_type())
|
||||||
{
|
{
|
||||||
|
case Gizmos::Move:
|
||||||
|
{
|
||||||
|
// Apply new temporary offset
|
||||||
|
GLVolume* volume = m_volumes.volumes[m_mouse.drag.gizmo_volume_idx];
|
||||||
|
Vec3d offset = m_gizmos.get_position() - volume->get_offset();
|
||||||
|
for (GLVolume* v : volumes)
|
||||||
|
{
|
||||||
|
v->set_offset(v->get_offset() + offset);
|
||||||
|
}
|
||||||
|
update_position_values(volume->get_offset());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Gizmos::Scale:
|
case Gizmos::Scale:
|
||||||
{
|
{
|
||||||
// Apply new temporary scale factor
|
// Apply new temporary scale factor
|
||||||
|
@ -3182,8 +3251,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
for (GLVolume* v : volumes)
|
for (GLVolume* v : volumes)
|
||||||
{
|
{
|
||||||
v->set_scaling_factor((double)scale_factor);
|
v->set_scaling_factor((double)scale_factor);
|
||||||
update_scale_values((double)scale_factor);
|
|
||||||
}
|
}
|
||||||
|
update_scale_values((double)scale_factor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Gizmos::Rotate:
|
case Gizmos::Rotate:
|
||||||
|
@ -3193,8 +3262,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
for (GLVolume* v : volumes)
|
for (GLVolume* v : volumes)
|
||||||
{
|
{
|
||||||
v->set_rotation((double)angle_z);
|
v->set_rotation((double)angle_z);
|
||||||
update_rotation_value((double)angle_z, Z);
|
|
||||||
}
|
}
|
||||||
|
update_rotation_value((double)angle_z, Z);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -3304,6 +3373,27 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
{
|
{
|
||||||
switch (m_gizmos.get_current_type())
|
switch (m_gizmos.get_current_type())
|
||||||
{
|
{
|
||||||
|
case Gizmos::Move:
|
||||||
|
{
|
||||||
|
// get all volumes belonging to the same group, if any
|
||||||
|
std::vector<int> volume_idxs;
|
||||||
|
int vol_id = m_mouse.drag.gizmo_volume_idx;
|
||||||
|
int group_id = m_volumes.volumes[vol_id]->select_group_id;
|
||||||
|
if (group_id == -1)
|
||||||
|
volume_idxs.push_back(vol_id);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)m_volumes.volumes.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_volumes.volumes[i]->select_group_id == group_id)
|
||||||
|
volume_idxs.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_on_move(volume_idxs);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Gizmos::Scale:
|
case Gizmos::Scale:
|
||||||
{
|
{
|
||||||
m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
|
m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
|
||||||
|
@ -3759,6 +3849,7 @@ void GLCanvas3D::_deregister_callbacks()
|
||||||
m_on_enable_action_buttons_callback.deregister_callback();
|
m_on_enable_action_buttons_callback.deregister_callback();
|
||||||
m_on_gizmo_scale_uniformly_callback.deregister_callback();
|
m_on_gizmo_scale_uniformly_callback.deregister_callback();
|
||||||
m_on_gizmo_rotate_callback.deregister_callback();
|
m_on_gizmo_rotate_callback.deregister_callback();
|
||||||
|
m_on_gizmo_flatten_callback.deregister_callback();
|
||||||
m_on_update_geometry_info_callback.deregister_callback();
|
m_on_update_geometry_info_callback.deregister_callback();
|
||||||
|
|
||||||
m_action_add_callback.deregister_callback();
|
m_action_add_callback.deregister_callback();
|
||||||
|
|
|
@ -105,7 +105,6 @@ class GLCanvas3D
|
||||||
void reset() { first_volumes.clear(); }
|
void reset() { first_volumes.clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
enum EType : unsigned char
|
enum EType : unsigned char
|
||||||
|
@ -336,6 +335,7 @@ public:
|
||||||
enum EType : unsigned char
|
enum EType : unsigned char
|
||||||
{
|
{
|
||||||
Undefined,
|
Undefined,
|
||||||
|
Move,
|
||||||
Scale,
|
Scale,
|
||||||
Rotate,
|
Rotate,
|
||||||
Flatten,
|
Flatten,
|
||||||
|
@ -347,7 +347,6 @@ public:
|
||||||
typedef std::map<EType, GLGizmoBase*> GizmosMap;
|
typedef std::map<EType, GLGizmoBase*> GizmosMap;
|
||||||
GizmosMap m_gizmos;
|
GizmosMap m_gizmos;
|
||||||
EType m_current;
|
EType m_current;
|
||||||
bool m_dragging;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gizmos();
|
Gizmos();
|
||||||
|
@ -376,6 +375,9 @@ public:
|
||||||
void start_dragging(const BoundingBoxf3& box);
|
void start_dragging(const BoundingBoxf3& box);
|
||||||
void stop_dragging();
|
void stop_dragging();
|
||||||
|
|
||||||
|
Vec3d get_position() const;
|
||||||
|
void set_position(const Vec3d& position);
|
||||||
|
|
||||||
float get_scale() const;
|
float get_scale() const;
|
||||||
void set_scale(float scale);
|
void set_scale(float scale);
|
||||||
|
|
||||||
|
@ -438,7 +440,6 @@ public:
|
||||||
void render(const GLCanvas3D& canvas) const;
|
void render(const GLCanvas3D& canvas) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
wxGLCanvas* m_canvas;
|
wxGLCanvas* m_canvas;
|
||||||
wxGLContext* m_context;
|
wxGLContext* m_context;
|
||||||
LegendTexture m_legend_texture;
|
LegendTexture m_legend_texture;
|
||||||
|
@ -501,6 +502,7 @@ private:
|
||||||
PerlCallback m_on_enable_action_buttons_callback;
|
PerlCallback m_on_enable_action_buttons_callback;
|
||||||
PerlCallback m_on_gizmo_scale_uniformly_callback;
|
PerlCallback m_on_gizmo_scale_uniformly_callback;
|
||||||
PerlCallback m_on_gizmo_rotate_callback;
|
PerlCallback m_on_gizmo_rotate_callback;
|
||||||
|
PerlCallback m_on_gizmo_flatten_callback;
|
||||||
PerlCallback m_on_update_geometry_info_callback;
|
PerlCallback m_on_update_geometry_info_callback;
|
||||||
|
|
||||||
PerlCallback m_action_add_callback;
|
PerlCallback m_action_add_callback;
|
||||||
|
@ -557,6 +559,7 @@ public:
|
||||||
void set_drag_by(const std::string& value);
|
void set_drag_by(const std::string& value);
|
||||||
|
|
||||||
const std::string& get_select_by() const;
|
const std::string& get_select_by() const;
|
||||||
|
const std::string& get_drag_by() const;
|
||||||
|
|
||||||
float get_camera_zoom() const;
|
float get_camera_zoom() const;
|
||||||
|
|
||||||
|
@ -623,6 +626,7 @@ public:
|
||||||
void register_on_enable_action_buttons_callback(void* callback);
|
void register_on_enable_action_buttons_callback(void* callback);
|
||||||
void register_on_gizmo_scale_uniformly_callback(void* callback);
|
void register_on_gizmo_scale_uniformly_callback(void* callback);
|
||||||
void register_on_gizmo_rotate_callback(void* callback);
|
void register_on_gizmo_rotate_callback(void* callback);
|
||||||
|
void register_on_gizmo_flatten_callback(void* callback);
|
||||||
void register_on_update_geometry_info_callback(void* callback);
|
void register_on_update_geometry_info_callback(void* callback);
|
||||||
|
|
||||||
void register_action_add_callback(void* callback);
|
void register_action_add_callback(void* callback);
|
||||||
|
|
|
@ -700,6 +700,13 @@ void GLCanvas3DManager::register_on_gizmo_rotate_callback(wxGLCanvas* canvas, vo
|
||||||
it->second->register_on_gizmo_rotate_callback(callback);
|
it->second->register_on_gizmo_rotate_callback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLCanvas3DManager::register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback)
|
||||||
|
{
|
||||||
|
CanvasesMap::iterator it = _get_canvas(canvas);
|
||||||
|
if (it != m_canvases.end())
|
||||||
|
it->second->register_on_gizmo_flatten_callback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3DManager::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
|
void GLCanvas3DManager::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
|
||||||
{
|
{
|
||||||
CanvasesMap::iterator it = _get_canvas(canvas);
|
CanvasesMap::iterator it = _get_canvas(canvas);
|
||||||
|
|
|
@ -163,6 +163,7 @@ public:
|
||||||
void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
|
void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
|
||||||
void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
|
||||||
void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
|
void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
void register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback);
|
||||||
void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
|
void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
|
||||||
void register_action_add_callback(wxGLCanvas* canvas, void* callback);
|
void register_action_add_callback(wxGLCanvas* canvas, void* callback);
|
||||||
|
|
|
@ -103,20 +103,22 @@ namespace GUI {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float GLGizmoBase::Grabber::HalfSize = 2.0f;
|
const float GLGizmoBase::Grabber::SizeFactor = 0.025f;
|
||||||
|
const float GLGizmoBase::Grabber::MinHalfSize = 1.5f;
|
||||||
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
|
const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
|
||||||
|
|
||||||
GLGizmoBase::Grabber::Grabber()
|
GLGizmoBase::Grabber::Grabber()
|
||||||
: center(Vec3d::Zero())
|
: center(Vec3d::Zero())
|
||||||
, angles(Vec3d::Zero())
|
, angles(Vec3d::Zero())
|
||||||
, dragging(false)
|
, dragging(false)
|
||||||
|
, enabled(true)
|
||||||
{
|
{
|
||||||
color[0] = 1.0f;
|
color[0] = 1.0f;
|
||||||
color[1] = 1.0f;
|
color[1] = 1.0f;
|
||||||
color[2] = 1.0f;
|
color[2] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::Grabber::render(bool hover) const
|
void GLGizmoBase::Grabber::render(bool hover, const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
float render_color[3];
|
float render_color[3];
|
||||||
if (hover)
|
if (hover)
|
||||||
|
@ -128,12 +130,15 @@ void GLGizmoBase::Grabber::render(bool hover) const
|
||||||
else
|
else
|
||||||
::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float));
|
::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float));
|
||||||
|
|
||||||
render(render_color, true);
|
render(box, render_color, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::Grabber::render(const float* render_color, bool use_lighting) const
|
void GLGizmoBase::Grabber::render(const BoundingBoxf3& box, const float* render_color, bool use_lighting) const
|
||||||
{
|
{
|
||||||
float half_size = dragging ? HalfSize * DraggingScaleFactor : HalfSize;
|
float max_size = (float)box.max_size();
|
||||||
|
float half_size = dragging ? max_size * SizeFactor * DraggingScaleFactor : max_size * SizeFactor;
|
||||||
|
half_size = std::max(half_size, MinHalfSize);
|
||||||
|
|
||||||
if (use_lighting)
|
if (use_lighting)
|
||||||
::glEnable(GL_LIGHTING);
|
::glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
@ -234,6 +239,22 @@ void GLGizmoBase::set_highlight_color(const float* color)
|
||||||
::memcpy((void*)m_highlight_color, (const void*)color, 3 * sizeof(float));
|
::memcpy((void*)m_highlight_color, (const void*)color, 3 * sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoBase::enable_grabber(unsigned int id)
|
||||||
|
{
|
||||||
|
if ((0 <= id) && (id < (unsigned int)m_grabbers.size()))
|
||||||
|
m_grabbers[id].enabled = true;
|
||||||
|
|
||||||
|
on_enable_grabber(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoBase::disable_grabber(unsigned int id)
|
||||||
|
{
|
||||||
|
if ((0 <= id) && (id < (unsigned int)m_grabbers.size()))
|
||||||
|
m_grabbers[id].enabled = false;
|
||||||
|
|
||||||
|
on_disable_grabber(id);
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoBase::start_dragging(const BoundingBoxf3& box)
|
void GLGizmoBase::start_dragging(const BoundingBoxf3& box)
|
||||||
{
|
{
|
||||||
m_dragging = true;
|
m_dragging = true;
|
||||||
|
@ -274,22 +295,26 @@ float GLGizmoBase::picking_color_component(unsigned int id) const
|
||||||
return (float)color / 255.0f;
|
return (float)color / 255.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::render_grabbers() const
|
void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)m_grabbers.size(); ++i)
|
for (int i = 0; i < (int)m_grabbers.size(); ++i)
|
||||||
{
|
{
|
||||||
m_grabbers[i].render(m_hover_id == i);
|
if (m_grabbers[i].enabled)
|
||||||
|
m_grabbers[i].render((m_hover_id == i), box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoBase::render_grabbers_for_picking() const
|
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i)
|
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_grabbers[i].enabled)
|
||||||
{
|
{
|
||||||
m_grabbers[i].color[0] = 1.0f;
|
m_grabbers[i].color[0] = 1.0f;
|
||||||
m_grabbers[i].color[1] = 1.0f;
|
m_grabbers[i].color[1] = 1.0f;
|
||||||
m_grabbers[i].color[2] = picking_color_component(i);
|
m_grabbers[i].color[2] = picking_color_component(i);
|
||||||
m_grabbers[i].render_for_picking();
|
m_grabbers[i].render_for_picking(box);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +411,9 @@ void GLGizmoRotate::on_update(const Linef3& mouse_ray)
|
||||||
|
|
||||||
void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
|
void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
|
if (!m_grabbers[0].enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_dragging)
|
if (m_dragging)
|
||||||
set_tooltip(format(m_angle * 180.0f / (float)PI, 4));
|
set_tooltip(format(m_angle * 180.0f / (float)PI, 4));
|
||||||
else
|
else
|
||||||
|
@ -416,7 +444,7 @@ void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
|
||||||
if (m_hover_id != -1)
|
if (m_hover_id != -1)
|
||||||
render_angle();
|
render_angle();
|
||||||
|
|
||||||
render_grabber();
|
render_grabber(box);
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
|
@ -428,7 +456,7 @@ void GLGizmoRotate::on_render_for_picking(const BoundingBoxf3& box) const
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
|
|
||||||
transform_to_local();
|
transform_to_local();
|
||||||
render_grabbers_for_picking();
|
render_grabbers_for_picking(box);
|
||||||
|
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
|
@ -520,7 +548,7 @@ void GLGizmoRotate::render_angle() const
|
||||||
::glEnd();
|
::glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoRotate::render_grabber() const
|
void GLGizmoRotate::render_grabber(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
double grabber_radius = (double)(m_radius + GrabberOffset);
|
double grabber_radius = (double)(m_radius + GrabberOffset);
|
||||||
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
|
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
|
||||||
|
@ -534,7 +562,7 @@ void GLGizmoRotate::render_grabber() const
|
||||||
::glEnd();
|
::glEnd();
|
||||||
|
|
||||||
::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float));
|
::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float));
|
||||||
render_grabbers();
|
render_grabbers(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoRotate::transform_to_local() const
|
void GLGizmoRotate::transform_to_local() const
|
||||||
|
@ -665,6 +693,7 @@ void GLGizmoRotate3D::on_render(const BoundingBoxf3& box) const
|
||||||
}
|
}
|
||||||
|
|
||||||
const float GLGizmoScale3D::Offset = 5.0f;
|
const float GLGizmoScale3D::Offset = 5.0f;
|
||||||
|
const Vec3d GLGizmoScale3D::OffsetVec = (double)GLGizmoScale3D::Offset * Vec3d::Ones();
|
||||||
|
|
||||||
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent)
|
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent)
|
||||||
: GLGizmoBase(parent)
|
: GLGizmoBase(parent)
|
||||||
|
@ -714,7 +743,7 @@ void GLGizmoScale3D::on_start_dragging(const BoundingBoxf3& box)
|
||||||
{
|
{
|
||||||
m_starting_drag_position = m_grabbers[m_hover_id].center;
|
m_starting_drag_position = m_grabbers[m_hover_id].center;
|
||||||
m_show_starting_box = true;
|
m_show_starting_box = true;
|
||||||
m_starting_box = box;
|
m_starting_box = BoundingBoxf3(box.min - OffsetVec, box.max + OffsetVec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,9 +777,7 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
|
|
||||||
::glEnable(GL_DEPTH_TEST);
|
::glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
Vec3d offset_vec = (double)Offset * Vec3d::Ones();
|
m_box = BoundingBoxf3(box.min - OffsetVec, box.max + OffsetVec);
|
||||||
|
|
||||||
m_box = BoundingBoxf3(box.min - offset_vec, box.max + offset_vec);
|
|
||||||
const Vec3d& center = m_box.center();
|
const Vec3d& center = m_box.center();
|
||||||
|
|
||||||
// x axis
|
// x axis
|
||||||
|
@ -789,14 +816,23 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
::glColor3fv(m_base_color);
|
::glColor3fv(m_base_color);
|
||||||
render_box(m_box);
|
render_box(m_box);
|
||||||
// draw connections
|
// draw connections
|
||||||
|
if (m_grabbers[0].enabled && m_grabbers[1].enabled)
|
||||||
|
{
|
||||||
::glColor3fv(m_grabbers[0].color);
|
::glColor3fv(m_grabbers[0].color);
|
||||||
render_grabbers_connection(0, 1);
|
render_grabbers_connection(0, 1);
|
||||||
|
}
|
||||||
|
if (m_grabbers[2].enabled && m_grabbers[3].enabled)
|
||||||
|
{
|
||||||
::glColor3fv(m_grabbers[2].color);
|
::glColor3fv(m_grabbers[2].color);
|
||||||
render_grabbers_connection(2, 3);
|
render_grabbers_connection(2, 3);
|
||||||
|
}
|
||||||
|
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
||||||
|
{
|
||||||
::glColor3fv(m_grabbers[4].color);
|
::glColor3fv(m_grabbers[4].color);
|
||||||
render_grabbers_connection(4, 5);
|
render_grabbers_connection(4, 5);
|
||||||
|
}
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
render_grabbers();
|
render_grabbers(m_box);
|
||||||
}
|
}
|
||||||
else if ((m_hover_id == 0) || (m_hover_id == 1))
|
else if ((m_hover_id == 0) || (m_hover_id == 1))
|
||||||
{
|
{
|
||||||
|
@ -813,8 +849,8 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
::glColor3fv(m_grabbers[0].color);
|
::glColor3fv(m_grabbers[0].color);
|
||||||
render_grabbers_connection(0, 1);
|
render_grabbers_connection(0, 1);
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
m_grabbers[0].render(true);
|
m_grabbers[0].render(true, m_box);
|
||||||
m_grabbers[1].render(true);
|
m_grabbers[1].render(true, m_box);
|
||||||
}
|
}
|
||||||
else if ((m_hover_id == 2) || (m_hover_id == 3))
|
else if ((m_hover_id == 2) || (m_hover_id == 3))
|
||||||
{
|
{
|
||||||
|
@ -831,8 +867,8 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
::glColor3fv(m_grabbers[2].color);
|
::glColor3fv(m_grabbers[2].color);
|
||||||
render_grabbers_connection(2, 3);
|
render_grabbers_connection(2, 3);
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
m_grabbers[2].render(true);
|
m_grabbers[2].render(true, m_box);
|
||||||
m_grabbers[3].render(true);
|
m_grabbers[3].render(true, m_box);
|
||||||
}
|
}
|
||||||
else if ((m_hover_id == 4) || (m_hover_id == 5))
|
else if ((m_hover_id == 4) || (m_hover_id == 5))
|
||||||
{
|
{
|
||||||
|
@ -849,8 +885,8 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
::glColor3fv(m_grabbers[4].color);
|
::glColor3fv(m_grabbers[4].color);
|
||||||
render_grabbers_connection(4, 5);
|
render_grabbers_connection(4, 5);
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
m_grabbers[4].render(true);
|
m_grabbers[4].render(true, m_box);
|
||||||
m_grabbers[5].render(true);
|
m_grabbers[5].render(true, m_box);
|
||||||
}
|
}
|
||||||
else if (m_hover_id >= 6)
|
else if (m_hover_id >= 6)
|
||||||
{
|
{
|
||||||
|
@ -866,7 +902,7 @@ void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
for (int i = 6; i < 10; ++i)
|
for (int i = 6; i < 10; ++i)
|
||||||
{
|
{
|
||||||
m_grabbers[i].render(true);
|
m_grabbers[i].render(true, m_box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,7 +911,7 @@ void GLGizmoScale3D::on_render_for_picking(const BoundingBoxf3& box) const
|
||||||
{
|
{
|
||||||
::glDisable(GL_DEPTH_TEST);
|
::glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
render_grabbers_for_picking();
|
render_grabbers_for_picking(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::render_box(const BoundingBoxf3& box) const
|
void GLGizmoScale3D::render_box(const BoundingBoxf3& box) const
|
||||||
|
@ -989,6 +1025,160 @@ double GLGizmoScale3D::calc_ratio(unsigned int preferred_plane_id, const Linef3&
|
||||||
return ratio;
|
return ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double GLGizmoMove3D::Offset = 10.0;
|
||||||
|
|
||||||
|
GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent)
|
||||||
|
: GLGizmoBase(parent)
|
||||||
|
, m_position(Vec3d::Zero())
|
||||||
|
, m_starting_drag_position(Vec3d::Zero())
|
||||||
|
, m_starting_box_center(Vec3d::Zero())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLGizmoMove3D::on_init()
|
||||||
|
{
|
||||||
|
std::string path = resources_dir() + "/icons/overlay/";
|
||||||
|
|
||||||
|
std::string filename = path + "move_off.png";
|
||||||
|
if (!m_textures[Off].load_from_file(filename, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
filename = path + "move_hover.png";
|
||||||
|
if (!m_textures[Hover].load_from_file(filename, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
filename = path + "move_on.png";
|
||||||
|
if (!m_textures[On].load_from_file(filename, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
m_grabbers.push_back(Grabber());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::on_start_dragging(const BoundingBoxf3& box)
|
||||||
|
{
|
||||||
|
if (m_hover_id != -1)
|
||||||
|
{
|
||||||
|
m_starting_drag_position = m_grabbers[m_hover_id].center;
|
||||||
|
m_starting_box_center = box.center();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::on_update(const Linef3& mouse_ray)
|
||||||
|
{
|
||||||
|
if (m_hover_id == 0)
|
||||||
|
m_position(0) = 2.0 * m_starting_box_center(0) + calc_displacement(1, mouse_ray) - m_starting_drag_position(0);
|
||||||
|
else if (m_hover_id == 1)
|
||||||
|
m_position(1) = 2.0 * m_starting_box_center(1) + calc_displacement(2, mouse_ray) - m_starting_drag_position(1);
|
||||||
|
else if (m_hover_id == 2)
|
||||||
|
m_position(2) = 2.0 * m_starting_box_center(2) + calc_displacement(1, mouse_ray) - m_starting_drag_position(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::on_render(const BoundingBoxf3& box) const
|
||||||
|
{
|
||||||
|
if (m_grabbers[0].dragging)
|
||||||
|
set_tooltip("X: " + format(m_position(0), 2));
|
||||||
|
else if (m_grabbers[1].dragging)
|
||||||
|
set_tooltip("Y: " + format(m_position(1), 2));
|
||||||
|
else if (m_grabbers[2].dragging)
|
||||||
|
set_tooltip("Z: " + format(m_position(2), 2));
|
||||||
|
|
||||||
|
::glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
const Vec3d& center = box.center();
|
||||||
|
|
||||||
|
// x axis
|
||||||
|
m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2));
|
||||||
|
::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 3 * sizeof(float));
|
||||||
|
|
||||||
|
// y axis
|
||||||
|
m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2));
|
||||||
|
::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 3 * sizeof(float));
|
||||||
|
|
||||||
|
// z axis
|
||||||
|
m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset);
|
||||||
|
::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float));
|
||||||
|
|
||||||
|
::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
|
||||||
|
|
||||||
|
if (m_hover_id == -1)
|
||||||
|
{
|
||||||
|
// draw axes
|
||||||
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (m_grabbers[i].enabled)
|
||||||
|
{
|
||||||
|
::glColor3fv(AXES_COLOR[i]);
|
||||||
|
::glBegin(GL_LINES);
|
||||||
|
::glVertex3f(center(0), center(1), center(2));
|
||||||
|
::glVertex3f((GLfloat)m_grabbers[i].center(0), (GLfloat)m_grabbers[i].center(1), (GLfloat)m_grabbers[i].center(2));
|
||||||
|
::glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw grabbers
|
||||||
|
render_grabbers(box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// draw axis
|
||||||
|
::glColor3fv(AXES_COLOR[m_hover_id]);
|
||||||
|
::glBegin(GL_LINES);
|
||||||
|
::glVertex3f(center(0), center(1), center(2));
|
||||||
|
::glVertex3f((GLfloat)m_grabbers[m_hover_id].center(0), (GLfloat)m_grabbers[m_hover_id].center(1), (GLfloat)m_grabbers[m_hover_id].center(2));
|
||||||
|
::glEnd();
|
||||||
|
|
||||||
|
// draw grabber
|
||||||
|
m_grabbers[m_hover_id].render(true, box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::on_render_for_picking(const BoundingBoxf3& box) const
|
||||||
|
{
|
||||||
|
::glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
render_grabbers_for_picking(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
double GLGizmoMove3D::calc_displacement(unsigned int preferred_plane_id, const Linef3& mouse_ray) const
|
||||||
|
{
|
||||||
|
double displacement = 0.0;
|
||||||
|
|
||||||
|
Vec3d starting_vec = m_starting_drag_position - m_starting_box_center;
|
||||||
|
double len_starting_vec = starting_vec.norm();
|
||||||
|
if (len_starting_vec == 0.0)
|
||||||
|
return displacement;
|
||||||
|
|
||||||
|
Vec3d starting_vec_dir = starting_vec.normalized();
|
||||||
|
Vec3d mouse_dir = mouse_ray.unit_vector();
|
||||||
|
|
||||||
|
unsigned int plane_id = select_best_plane(mouse_dir, preferred_plane_id);
|
||||||
|
|
||||||
|
switch (plane_id)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
displacement = starting_vec_dir.dot(intersection_on_plane_xy(mouse_ray, m_starting_box_center));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
displacement = starting_vec_dir.dot(intersection_on_plane_xz(mouse_ray, m_starting_box_center));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
displacement = starting_vec_dir.dot(intersection_on_plane_yz(mouse_ray, m_starting_box_center));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return displacement;
|
||||||
|
}
|
||||||
|
|
||||||
GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent)
|
GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent)
|
||||||
: GLGizmoBase(parent)
|
: GLGizmoBase(parent)
|
||||||
|
|
|
@ -22,21 +22,23 @@ class GLGizmoBase
|
||||||
protected:
|
protected:
|
||||||
struct Grabber
|
struct Grabber
|
||||||
{
|
{
|
||||||
static const float HalfSize;
|
static const float SizeFactor;
|
||||||
|
static const float MinHalfSize;
|
||||||
static const float DraggingScaleFactor;
|
static const float DraggingScaleFactor;
|
||||||
|
|
||||||
Vec3d center;
|
Vec3d center;
|
||||||
Vec3d angles;
|
Vec3d angles;
|
||||||
float color[3];
|
float color[3];
|
||||||
|
bool enabled;
|
||||||
bool dragging;
|
bool dragging;
|
||||||
|
|
||||||
Grabber();
|
Grabber();
|
||||||
|
|
||||||
void render(bool hover) const;
|
void render(bool hover, const BoundingBoxf3& box) const;
|
||||||
void render_for_picking() const { render(color, false); }
|
void render_for_picking(const BoundingBoxf3& box) const { render(box, color, false); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render(const float* render_color, bool use_lighting) const;
|
void render(const BoundingBoxf3& box, const float* render_color, bool use_lighting) const;
|
||||||
void render_face(float half_size) const;
|
void render_face(float half_size) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,6 +85,9 @@ public:
|
||||||
|
|
||||||
void set_highlight_color(const float* color);
|
void set_highlight_color(const float* color);
|
||||||
|
|
||||||
|
void enable_grabber(unsigned int id);
|
||||||
|
void disable_grabber(unsigned int id);
|
||||||
|
|
||||||
void start_dragging(const BoundingBoxf3& box);
|
void start_dragging(const BoundingBoxf3& box);
|
||||||
void stop_dragging();
|
void stop_dragging();
|
||||||
bool is_dragging() const { return m_dragging; }
|
bool is_dragging() const { return m_dragging; }
|
||||||
|
@ -96,6 +101,8 @@ protected:
|
||||||
virtual bool on_init() = 0;
|
virtual bool on_init() = 0;
|
||||||
virtual void on_set_state() {}
|
virtual void on_set_state() {}
|
||||||
virtual void on_set_hover_id() {}
|
virtual void on_set_hover_id() {}
|
||||||
|
virtual void on_enable_grabber(unsigned int id) {}
|
||||||
|
virtual void on_disable_grabber(unsigned int id) {}
|
||||||
virtual void on_start_dragging(const BoundingBoxf3& box) {}
|
virtual void on_start_dragging(const BoundingBoxf3& box) {}
|
||||||
virtual void on_stop_dragging() {}
|
virtual void on_stop_dragging() {}
|
||||||
virtual void on_update(const Linef3& mouse_ray) = 0;
|
virtual void on_update(const Linef3& mouse_ray) = 0;
|
||||||
|
@ -103,8 +110,8 @@ protected:
|
||||||
virtual void on_render_for_picking(const BoundingBoxf3& box) const = 0;
|
virtual void on_render_for_picking(const BoundingBoxf3& box) const = 0;
|
||||||
|
|
||||||
float picking_color_component(unsigned int id) const;
|
float picking_color_component(unsigned int id) const;
|
||||||
void render_grabbers() const;
|
void render_grabbers(const BoundingBoxf3& box) const;
|
||||||
void render_grabbers_for_picking() const;
|
void render_grabbers_for_picking(const BoundingBoxf3& box) const;
|
||||||
|
|
||||||
void set_tooltip(const std::string& tooltip) const;
|
void set_tooltip(const std::string& tooltip) const;
|
||||||
std::string format(float value, unsigned int decimals) const;
|
std::string format(float value, unsigned int decimals) const;
|
||||||
|
@ -157,7 +164,7 @@ private:
|
||||||
void render_snap_radii() const;
|
void render_snap_radii() const;
|
||||||
void render_reference_radius() const;
|
void render_reference_radius() const;
|
||||||
void render_angle() const;
|
void render_angle() const;
|
||||||
void render_grabber() const;
|
void render_grabber(const BoundingBoxf3& box) const;
|
||||||
|
|
||||||
void transform_to_local() const;
|
void transform_to_local() const;
|
||||||
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
|
||||||
|
@ -196,6 +203,16 @@ protected:
|
||||||
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
|
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
virtual void on_enable_grabber(unsigned int id)
|
||||||
|
{
|
||||||
|
if ((0 <= id) && (id < 3))
|
||||||
|
m_gizmos[id].enable_grabber(0);
|
||||||
|
}
|
||||||
|
virtual void on_disable_grabber(unsigned int id)
|
||||||
|
{
|
||||||
|
if ((0 <= id) && (id < 3))
|
||||||
|
m_gizmos[id].disable_grabber(0);
|
||||||
|
}
|
||||||
virtual void on_start_dragging(const BoundingBoxf3& box);
|
virtual void on_start_dragging(const BoundingBoxf3& box);
|
||||||
virtual void on_stop_dragging();
|
virtual void on_stop_dragging();
|
||||||
virtual void on_update(const Linef3& mouse_ray)
|
virtual void on_update(const Linef3& mouse_ray)
|
||||||
|
@ -218,6 +235,7 @@ protected:
|
||||||
class GLGizmoScale3D : public GLGizmoBase
|
class GLGizmoScale3D : public GLGizmoBase
|
||||||
{
|
{
|
||||||
static const float Offset;
|
static const float Offset;
|
||||||
|
static const Vec3d OffsetVec;
|
||||||
|
|
||||||
mutable BoundingBoxf3 m_box;
|
mutable BoundingBoxf3 m_box;
|
||||||
|
|
||||||
|
@ -262,6 +280,31 @@ private:
|
||||||
double calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const;
|
double calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GLGizmoMove3D : public GLGizmoBase
|
||||||
|
{
|
||||||
|
static const double Offset;
|
||||||
|
|
||||||
|
Vec3d m_position;
|
||||||
|
Vec3d m_starting_drag_position;
|
||||||
|
Vec3d m_starting_box_center;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GLGizmoMove3D(GLCanvas3D& parent);
|
||||||
|
|
||||||
|
const Vec3d& get_position() const { return m_position; }
|
||||||
|
void set_position(const Vec3d& position) { m_position = position; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool on_init();
|
||||||
|
virtual void on_start_dragging(const BoundingBoxf3& box);
|
||||||
|
virtual void on_update(const Linef3& mouse_ray);
|
||||||
|
virtual void on_render(const BoundingBoxf3& box) const;
|
||||||
|
virtual void on_render_for_picking(const BoundingBoxf3& box) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
double calc_displacement(unsigned int preferred_plane_id, const Linef3& mouse_ray) const;
|
||||||
|
};
|
||||||
|
|
||||||
class GLGizmoFlatten : public GLGizmoBase
|
class GLGizmoFlatten : public GLGizmoBase
|
||||||
{
|
{
|
||||||
// This gizmo does not use grabbers. The m_hover_id relates to polygon managed by the class itself.
|
// This gizmo does not use grabbers. The m_hover_id relates to polygon managed by the class itself.
|
||||||
|
|
|
@ -651,6 +651,13 @@ register_on_gizmo_rotate_callback(canvas, callback)
|
||||||
CODE:
|
CODE:
|
||||||
_3DScene::register_on_gizmo_rotate_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
|
_3DScene::register_on_gizmo_rotate_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
|
||||||
|
|
||||||
|
void
|
||||||
|
register_on_gizmo_flatten_callback(canvas, callback)
|
||||||
|
SV *canvas;
|
||||||
|
SV *callback;
|
||||||
|
CODE:
|
||||||
|
_3DScene::register_on_gizmo_flatten_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
|
||||||
|
|
||||||
void
|
void
|
||||||
register_on_update_geometry_info_callback(canvas, callback)
|
register_on_update_geometry_info_callback(canvas, callback)
|
||||||
SV *canvas;
|
SV *canvas;
|
||||||
|
|
Loading…
Reference in a new issue