Autocenter finally disabled. Progress indication works.

This commit is contained in:
tamasmeszaros 2018-06-29 17:46:21 +02:00
parent d3b19382fe
commit 952068f282
6 changed files with 108 additions and 55 deletions

View file

@ -1192,13 +1192,14 @@ sub arrange {
# my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape); # my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape);
# my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb); # my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb);
# Update is not implemented in C++ so we cannot call this for now
$self->{appController}->arrange_model; $self->{appController}->arrange_model;
# ignore arrange failures on purpose: user has visual feedback and we don't need to warn him # ignore arrange failures on purpose: user has visual feedback and we don't need to warn him
# when parts don't fit in print bed # when parts don't fit in print bed
# Force auto center of the aligned grid of of objects on the print bed. # Force auto center of the aligned grid of of objects on the print bed.
$self->update(1); $self->update(0);
} }
sub split_object { sub split_object {

View file

@ -20,7 +20,7 @@
#include <boost/nowide/iostream.hpp> #include <boost/nowide/iostream.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <benchmark.h> // #include <benchmark.h>
namespace Slic3r { namespace Slic3r {
@ -387,17 +387,17 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
// Create the arranger config // Create the arranger config
auto min_obj_distance = static_cast<Coord>(dist/SCALING_FACTOR); auto min_obj_distance = static_cast<Coord>(dist/SCALING_FACTOR);
Benchmark bench; // Benchmark bench;
std::cout << "Creating model siluett..." << std::endl; // std::cout << "Creating model siluett..." << std::endl;
bench.start(); // bench.start();
// Get the 2D projected shapes with their 3D model instance pointers // Get the 2D projected shapes with their 3D model instance pointers
auto shapemap = arr::projectModelFromTop(model); auto shapemap = arr::projectModelFromTop(model);
bench.stop(); // bench.stop();
std::cout << "Model siluett created in " << bench.getElapsedSec() // std::cout << "Model siluett created in " << bench.getElapsedSec()
<< " seconds. " << "Min object distance = " << min_obj_distance << std::endl; // << " seconds. " << "Min object distance = " << min_obj_distance << std::endl;
// std::cout << "{" << std::endl; // std::cout << "{" << std::endl;
// std::for_each(shapemap.begin(), shapemap.end(), // std::for_each(shapemap.begin(), shapemap.end(),
@ -436,7 +436,8 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
biggest = &item; biggest = &item;
} }
} }
if(it.second.vertexCount() > 3) shapes.push_back(std::ref(it.second)); /*if(it.second.vertexCount() > 3)*/
shapes.push_back(std::ref(it.second));
}); });
Box bin; Box bin;
@ -468,27 +469,27 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
scfg.try_reverse_order = false; scfg.try_reverse_order = false;
scfg.force_parallel = true; scfg.force_parallel = true;
pcfg.alignment = Arranger::PlacementConfig::Alignment::CENTER; pcfg.alignment = Arranger::PlacementConfig::Alignment::CENTER;
// TODO cannot use rotations until multiple objects of same geometry can
// handle different rotations
// arranger.useMinimumBoundigBoxRotation();
pcfg.rotations = { 0.0 };
Arranger arranger(bin, min_obj_distance, pcfg, scfg); Arranger arranger(bin, min_obj_distance, pcfg, scfg);
arranger.useMinimumBoundigBoxRotation();
arranger.progressIndicator(progressind); arranger.progressIndicator(progressind);
std::cout << "Arranging model..." << std::endl; // std::cout << "Arranging model..." << std::endl;
bench.start(); // bench.start();
// Arrange and return the items with their respective indices within the // Arrange and return the items with their respective indices within the
// input sequence. // input sequence.
ArrangeResult result; auto result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
try {
result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
} catch(std::exception& e) {
std::cerr << "An exception occured: " << e.what() << std::endl;
}
bench.stop(); // bench.stop();
std::cout << "Model arranged in " << bench.getElapsedSec() // std::cout << "Model arranged in " << bench.getElapsedSec()
<< " seconds." << std::endl; // << " seconds." << std::endl;
auto applyResult = [&shapemap](ArrangeResult::value_type& group, auto applyResult = [&shapemap](ArrangeResult::value_type& group,
@ -505,29 +506,25 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
// appropriately // appropriately
auto off = item.translation(); auto off = item.translation();
Radians rot = item.rotation(); Radians rot = item.rotation();
Pointf foff(off.X*SCALING_FACTOR, Pointf foff(off.X*SCALING_FACTOR + batch_offset,
off.Y*SCALING_FACTOR); off.Y*SCALING_FACTOR);
// write the tranformation data into the model instance // write the tranformation data into the model instance
inst_ptr->rotation = rot; inst_ptr->rotation = rot;
inst_ptr->offset = foff; inst_ptr->offset = foff;
inst_ptr->offset_z = -batch_offset;
} }
}; };
std::cout << "Applying result..." << std::endl; // std::cout << "Applying result..." << std::endl;
bench.start(); // bench.start();
if(first_bin_only) { if(first_bin_only) {
applyResult(result.front(), 0); applyResult(result.front(), 0);
} else { } else {
const auto STRIDE_PADDING = 1.2; const auto STRIDE_PADDING = 1.2;
const auto MIN_STRIDE = 100;
auto h = STRIDE_PADDING * model.bounding_box().size().z;
h = h < MIN_STRIDE ? MIN_STRIDE : h;
Coord stride = static_cast<Coord>(h);
Coord stride = static_cast<Coord>(STRIDE_PADDING*
bin.width()*SCALING_FACTOR);
Coord batch_offset = 0; Coord batch_offset = 0;
for(auto& group : result) { for(auto& group : result) {
@ -539,9 +536,9 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
batch_offset += stride; batch_offset += stride;
} }
} }
bench.stop(); // bench.stop();
std::cout << "Result applied in " << bench.getElapsedSec() // std::cout << "Result applied in " << bench.getElapsedSec()
<< " seconds." << std::endl; // << " seconds." << std::endl;
for(auto objptr : model.objects) objptr->invalidate_bounding_box(); for(auto objptr : model.objects) objptr->invalidate_bounding_box();
@ -556,8 +553,7 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb,
{ {
bool ret = false; bool ret = false;
if(bb != nullptr && bb->defined) { if(bb != nullptr && bb->defined) {
const bool FIRST_BIN_ONLY = false; ret = arr::arrange(*this, dist, bb, false, progressind);
ret = arr::arrange(*this, dist, bb, FIRST_BIN_ONLY, progressind);
} else { } else {
// get the (transformed) size of each instance so that we take // get the (transformed) size of each instance so that we take
// into account their different transformations when packing // into account their different transformations when packing
@ -1266,7 +1262,7 @@ void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) cons
mesh->rotate_z(this->rotation); // rotate around mesh origin mesh->rotate_z(this->rotation); // rotate around mesh origin
mesh->scale(this->scaling_factor); // scale around mesh origin mesh->scale(this->scaling_factor); // scale around mesh origin
if (!dont_translate) if (!dont_translate)
mesh->translate(this->offset.x, this->offset.y, this->offset_z); mesh->translate(this->offset.x, this->offset.y, 0);
} }
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const

View file

@ -206,7 +206,6 @@ public:
double rotation; // Rotation around the Z axis, in radians around mesh center point double rotation; // Rotation around the Z axis, in radians around mesh center point
double scaling_factor; double scaling_factor;
Pointf offset; // in unscaled coordinates Pointf offset; // in unscaled coordinates
double offset_z = 0;
ModelObject* get_object() const { return this->object; } ModelObject* get_object() const { return this->object; }

View file

@ -1,6 +1,7 @@
#include "AppController.hpp" #include "AppController.hpp"
#include <future> #include <future>
#include <chrono>
#include <sstream> #include <sstream>
#include <cstdarg> #include <cstdarg>
#include <thread> #include <thread>
@ -9,6 +10,7 @@
#include <slic3r/GUI/GUI.hpp> #include <slic3r/GUI/GUI.hpp>
#include <slic3r/GUI/PresetBundle.hpp> #include <slic3r/GUI/PresetBundle.hpp>
#include <Geometry.hpp>
#include <PrintConfig.hpp> #include <PrintConfig.hpp>
#include <Print.hpp> #include <Print.hpp>
#include <Model.hpp> #include <Model.hpp>
@ -58,14 +60,18 @@ void AppControllerBoilerplate::progress_indicator(
progressind_->m.unlock(); progressind_->m.unlock();
} }
void AppControllerBoilerplate::progress_indicator(unsigned statenum, AppControllerBoilerplate::ProgresIndicatorPtr
AppControllerBoilerplate::progress_indicator(
unsigned statenum,
const std::string &title, const std::string &title,
const std::string &firstmsg) const std::string &firstmsg)
{ {
progressind_->m.lock(); progressind_->m.lock();
progressind_->store[std::this_thread::get_id()] = auto ret = progressind_->store[std::this_thread::get_id()] =
create_progress_indicator(statenum, title, firstmsg);; create_progress_indicator(statenum, title, firstmsg);;
progressind_->m.unlock(); progressind_->m.unlock();
return ret;
} }
AppControllerBoilerplate::ProgresIndicatorPtr AppControllerBoilerplate::ProgresIndicatorPtr
@ -266,6 +272,11 @@ void PrintController::slice()
Slic3r::trace(3, "Slicing process finished."); Slic3r::trace(3, "Slicing process finished.");
} }
const PrintConfig &PrintController::config() const
{
return print_->config;
}
void IProgressIndicator::message_fmt( void IProgressIndicator::message_fmt(
const std::string &fmtstr, ...) { const std::string &fmtstr, ...) {
std::stringstream ss; std::stringstream ss;
@ -295,19 +306,46 @@ void IProgressIndicator::message_fmt(
void AppController::arrange_model() void AppController::arrange_model()
{ {
std::async(supports_asynch()? std::launch::async : std::launch::deferred, auto ftr = std::async(
supports_asynch()? std::launch::async : std::launch::deferred,
[this]() [this]()
{ {
// auto pind = progress_indicator(); unsigned count = 0;
for(auto obj : model_->objects) count += obj->instances.size();
// my $bb = Slic3r::Geometry::BoundingBoxf->new_from_points($self->{config}->bed_shape); auto pind = progress_indicator();
// my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb); auto pmax = pind->max();
// double dist = GUI::get_preset_bundle()->full_config().option("min_object_distance")->getFloat();
// std::cout << dist << std::endl; // Set the range of the progress to the object count
pind->max(count);
std::cout << "ITTT vagyok" << std::endl; auto dist = print_ctl()->config().min_object_distance();
BoundingBoxf bb(print_ctl()->config().bed_shape.values);
pind->update(0, "Arranging objects...");
try {
model_->arrange_objects(dist, &bb, [pind, count](unsigned rem){
pind->update(count - rem, "Arranging objects...");
}); });
} catch(std::exception& e) {
std::cerr << e.what() << std::endl;
report_issue(IssueType::ERR,
"Could not arrange model objects! "
"Some geometries may be invalid.",
"Exception occurred");
}
// Restore previous max value
pind->max(pmax);
pind->update(0, "Arranging done.");
});
while( ftr.wait_for(std::chrono::milliseconds(10))
!= std::future_status::ready) {
process_events();
}
} }
} }

View file

@ -14,6 +14,7 @@ namespace Slic3r {
class Model; class Model;
class Print; class Print;
class PrintObject; class PrintObject;
class PrintConfig;
/** /**
* @brief A boilerplate class for creating application logic. It should provide * @brief A boilerplate class for creating application logic. It should provide
@ -108,7 +109,7 @@ public:
* @param title The title of the procedure. * @param title The title of the procedure.
* @param firstmsg The message for the first subtask to be displayed. * @param firstmsg The message for the first subtask to be displayed.
*/ */
void progress_indicator(unsigned statenum, ProgresIndicatorPtr progress_indicator(unsigned statenum,
const std::string& title, const std::string& title,
const std::string& firstmsg = ""); const std::string& firstmsg = "");
@ -147,6 +148,8 @@ public:
*/ */
bool supports_asynch() const; bool supports_asynch() const;
void process_events();
protected: protected:
/** /**
@ -205,6 +208,8 @@ public:
* @brief Slice the loaded print scene. * @brief Slice the loaded print scene.
*/ */
void slice(); void slice();
const PrintConfig& config() const;
}; };
/** /**

View file

@ -25,6 +25,11 @@ bool AppControllerBoilerplate::supports_asynch() const
return true; return true;
} }
void AppControllerBoilerplate::process_events()
{
wxSafeYield();
}
AppControllerBoilerplate::PathList AppControllerBoilerplate::PathList
AppControllerBoilerplate::query_destination_paths( AppControllerBoilerplate::query_destination_paths(
const std::string &title, const std::string &title,
@ -79,7 +84,7 @@ bool AppControllerBoilerplate::report_issue(IssueType issuetype,
case IssueType::FATAL: icon = wxICON_ERROR; case IssueType::FATAL: icon = wxICON_ERROR;
} }
auto ret = wxMessageBox(description, brief, icon | style); auto ret = wxMessageBox(_(description), _(brief), icon | style);
return ret != wxCANCEL; return ret != wxCANCEL;
} }
@ -216,7 +221,7 @@ class Wrapper: public IProgressIndicator, public wxEvtHandler {
} }
void _state(unsigned st) { void _state(unsigned st) {
if( st <= max() ) { if( st <= IProgressIndicator::max() ) {
Base::state(st); Base::state(st);
if(!gauge_->IsShown()) showProgress(true); if(!gauge_->IsShown()) showProgress(true);
@ -253,7 +258,14 @@ public:
} }
virtual void state(float val) override { virtual void state(float val) override {
if(val >= 1.0) state(unsigned(val)); state(unsigned(val));
}
virtual void max(float val) override {
if(val > 1.0) {
gauge_->SetRange(static_cast<int>(val));
IProgressIndicator::max(val);
}
} }
void state(unsigned st) { void state(unsigned st) {
@ -261,7 +273,9 @@ public:
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_); auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
evt->SetInt(st); evt->SetInt(st);
wxQueueEvent(this, evt); wxQueueEvent(this, evt);
} else _state(st); } else {
_state(st);
}
} }
virtual void message(const std::string & msg) override { virtual void message(const std::string & msg) override {