Added selection and moving volumes to Plate3D

This commit is contained in:
Benjamin Landers 2018-06-25 03:44:31 -07:00
parent 7362e56578
commit 2258fd5978
5 changed files with 92 additions and 20 deletions

View File

@ -88,6 +88,9 @@ Plater::Plater(wxWindow* parent, const wxString& title) :
canvas3D = new Plate3D(preview_notebook, wxDefaultSize, objects, model, config);
preview_notebook->AddPage(canvas3D, _("3D"));
canvas3D->on_select_object = std::function<void (ObjIdx obj_idx)>(on_select_object);
canvas3D->on_instances_moved = std::function<void ()>(on_instances_moved);
preview3D = new Preview3D(preview_notebook, wxDefaultSize, objects, model, config);
preview_notebook->AddPage(preview3D, _("Preview"));
@ -494,6 +497,7 @@ void Plater::arrange() {
}
void Plater::on_model_change(bool force_autocenter) {
Log::info(LogChannel, L"Called on_modal_change");
// reload the select submenu (if already initialized)
{
@ -562,6 +566,7 @@ void Plater::select_object() {
void Plater::selection_changed() {
// Remove selection in 2D plater
this->canvas2D->set_selected(-1, -1);
this->canvas3D->selection_changed();
auto obj = this->selected_object();
bool have_sel {obj != this->objects.end()};

View File

@ -6,30 +6,74 @@ namespace Slic3r { namespace GUI {
Plate3D::Plate3D(wxWindow* parent, const wxSize& size, std::vector<PlaterObject>& _objects, std::shared_ptr<Model> _model, std::shared_ptr<Config> _config) :
Scene3D(parent, size), objects(_objects), model(_model), config(_config)
{
//this->glContext = new wxGLContext(this);
//this->Bind(wxEVT_PAINT, [this](wxPaintEvent& e) { this->repaint(e); });
//delete this->glContext;
//this->glContext = new wxGLContext(this); // Update glContext (look for better way)
//});
// Bind the varying mouse events
// Bind the extra mouse events
this->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { this->mouse_down(e); });
this->Bind(wxEVT_RIGHT_DOWN, [this](wxMouseEvent &e) { this->mouse_down(e); });
}
void Plate3D::mouse_down(wxMouseEvent &e){
if(!hover){
//select logic
if(hover){
on_select_object(hover_object);
moving = true;
moving_volume = hover_volume;
move_start = Point(e.GetX(),e.GetY());
}else{
on_select_object(-1);
}
hover = false;
}
void Plate3D::mouse_up(wxMouseEvent &e){
if(moving){
//translate object
moving = false;
uint i = 0;
for(const PlaterObject &object: objects){
const auto &modelobj = model->objects.at(object.identifier);
for(ModelInstance *instance: modelobj->instances){
uint size = modelobj->volumes.size();
if(i <= moving_volume && moving_volume < i+size){
instance->offset.translate(volumes.at(i).origin);
modelobj->update_bounding_box();
on_instances_moved();
Refresh();
return;
}else{
i+=size;
}
}
}
}
Scene3D::mouse_up(e);
}
void Plate3D::mouse_move(wxMouseEvent &e){
if(!e.Dragging()){
pos = Point(e.GetX(),e.GetY());
mouse = true;
Refresh();
} else if(moving){
const auto p = Point(e.GetX(),e.GetY());
const auto current = mouse_ray(p).intersect_plane(0);
const auto old = mouse_ray(move_start).intersect_plane(0);
move_start = p;
uint i = 0;
for(const PlaterObject &object: objects){
const auto &modelobj = model->objects.at(object.identifier);
for(ModelInstance *instance: modelobj->instances){
uint size = modelobj->volumes.size();
if(i <= moving_volume && moving_volume < i+size){
for(ModelVolume* volume: modelobj->volumes){
volumes.at(i).origin.translate(old.vector_to(current));
i++;
}
Refresh();
return;
}else{
i+=size;
}
}
}
} else {
Scene3D::mouse_move(e);
}
@ -47,32 +91,37 @@ void Plate3D::update(){
}
}
color_volumes();
Refresh();
}
void Plate3D::color_volumes(){
uint i = 0;
for(const PlaterObject &object: objects){
const auto &modelobj = model->objects.at(object.identifier);
bool hover_object = hover && i <= hover_volume && hover_volume < i+modelobj->instances.size()*modelobj->volumes.size();
for(ModelInstance *instance: modelobj->instances){
for(ModelVolume* volume: modelobj->volumes){
auto& rendervolume = volumes.at(i);
if(object.selected){
rendervolume.color = ui_settings->color->SELECTED_COLOR();
}else{
}else if(hover_object){
rendervolume.color = ui_settings->color->HOVER_COLOR();
} else {
rendervolume.color = ui_settings->color->COLOR_PARTS();
}
i++;
}
}
}
if(hover){
volumes.at(hover_volume).color = ui_settings->color->HOVER_COLOR();
}
}
void Plate3D::before_render(){
if (!mouse)return;
if (!mouse){
color_volumes();
return;
}
// Color each volume a different color, render and test which color is beneath the mouse.
//glDisable(GL_MULTISAMPLE) if ($self->{can_multisample});
glDisable(GL_LIGHTING);
uint i = 1;
@ -86,6 +135,8 @@ void Plate3D::before_render(){
GLubyte color[4] = {0,0,0,0};
glReadPixels(pos.x, GetSize().GetHeight()- pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
// Handle the hovered volume
uint index = (color[0]<<16) + (color[1]<<8) + color[2];
hover = false;
///*$self->_hover_volume_idx(undef);
@ -93,6 +144,15 @@ void Plate3D::before_render(){
if (index != 0 && index <= volumes.size()) {
hover = true;
hover_volume = index - 1;
uint k = 0;
for(const PlaterObject &object: objects){
const auto &modelobj = model->objects.at(object.identifier);
if(k <= hover_volume && hover_volume < k+modelobj->instances.size()*modelobj->volumes.size()){
hover_object = k;
break;
}
k++;
}
/*
$self->volumes->[$volume_idx]->hover(1);
my $group_id = $self->volumes->[$volume_idx]->select_group_id;

View File

@ -15,16 +15,22 @@ namespace Slic3r { namespace GUI {
class Plate3D : public Scene3D {
public:
void update();
/// Registered function to fire when objects are selected.
std::function<void (const unsigned int obj_idx)> on_select_object {};
/// Registered function to fire when an instance is moved.
std::function<void ()> on_instances_moved {};
void selection_changed(){Refresh();}
Plate3D(wxWindow* parent, const wxSize& size, std::vector<PlaterObject>& _objects, std::shared_ptr<Model> _model, std::shared_ptr<Config> _config);
protected:
void before_render();
void mouse_up(wxMouseEvent &e);
void mouse_move(wxMouseEvent &e);
void mouse_down(wxMouseEvent &e);
private:
void color_volumes();
Point pos;
bool hover = false, mouse = false;
uint hover_volume;
Point pos, move_start;
bool hover = false, mouse = false, moving = false;
uint hover_volume, hover_object, moving_volume;
std::vector<PlaterObject>& objects; //< reference to parent vector
std::shared_ptr<Slic3r::Model> model;
std::shared_ptr<Slic3r::Config> config;

View File

@ -47,7 +47,7 @@ float clamp(float low, float x, float high){
return x;
}
Linef3 mouse_ray(Point win){
Linef3 Scene3D::mouse_ray(Point win){
GLdouble proj[16], mview[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mview);
glGetDoublev(GL_PROJECTION_MATRIX, proj);

View File

@ -39,6 +39,7 @@ private:
void draw_ground();
void draw_axes(Pointf3 center, float length, int width, bool alwaysvisible);
protected:
Linef3 mouse_ray(Point win);
void draw_volumes();
virtual void mouse_up(wxMouseEvent &e);
virtual void mouse_move(wxMouseEvent &e);