Autocenter finally disabled. Progress indication works.
This commit is contained in:
parent
d3b19382fe
commit
952068f282
6 changed files with 108 additions and 55 deletions
|
@ -1192,13 +1192,14 @@ sub arrange {
|
|||
# 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);
|
||||
|
||||
# Update is not implemented in C++ so we cannot call this for now
|
||||
$self->{appController}->arrange_model;
|
||||
|
||||
# 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
|
||||
|
||||
# Force auto center of the aligned grid of of objects on the print bed.
|
||||
$self->update(1);
|
||||
$self->update(0);
|
||||
}
|
||||
|
||||
sub split_object {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <boost/nowide/iostream.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <benchmark.h>
|
||||
// #include <benchmark.h>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -387,17 +387,17 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
|
|||
// Create the arranger config
|
||||
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
|
||||
auto shapemap = arr::projectModelFromTop(model);
|
||||
bench.stop();
|
||||
// bench.stop();
|
||||
|
||||
std::cout << "Model siluett created in " << bench.getElapsedSec()
|
||||
<< " seconds. " << "Min object distance = " << min_obj_distance << std::endl;
|
||||
// std::cout << "Model siluett created in " << bench.getElapsedSec()
|
||||
// << " seconds. " << "Min object distance = " << min_obj_distance << std::endl;
|
||||
|
||||
// std::cout << "{" << std::endl;
|
||||
// std::for_each(shapemap.begin(), shapemap.end(),
|
||||
|
@ -436,7 +436,8 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
|
|||
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;
|
||||
|
@ -468,27 +469,27 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
|
|||
|
||||
scfg.try_reverse_order = false;
|
||||
scfg.force_parallel = true;
|
||||
|
||||
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.useMinimumBoundigBoxRotation();
|
||||
|
||||
arranger.progressIndicator(progressind);
|
||||
|
||||
std::cout << "Arranging model..." << std::endl;
|
||||
bench.start();
|
||||
// std::cout << "Arranging model..." << std::endl;
|
||||
// bench.start();
|
||||
// Arrange and return the items with their respective indices within the
|
||||
// input sequence.
|
||||
|
||||
ArrangeResult result;
|
||||
try {
|
||||
result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
|
||||
} catch(std::exception& e) {
|
||||
std::cerr << "An exception occured: " << e.what() << std::endl;
|
||||
}
|
||||
auto result = arranger.arrangeIndexed(shapes.begin(), shapes.end());
|
||||
|
||||
bench.stop();
|
||||
std::cout << "Model arranged in " << bench.getElapsedSec()
|
||||
<< " seconds." << std::endl;
|
||||
// bench.stop();
|
||||
// std::cout << "Model arranged in " << bench.getElapsedSec()
|
||||
// << " seconds." << std::endl;
|
||||
|
||||
|
||||
auto applyResult = [&shapemap](ArrangeResult::value_type& group,
|
||||
|
@ -505,29 +506,25 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
|
|||
// appropriately
|
||||
auto off = item.translation();
|
||||
Radians rot = item.rotation();
|
||||
Pointf foff(off.X*SCALING_FACTOR,
|
||||
Pointf foff(off.X*SCALING_FACTOR + batch_offset,
|
||||
off.Y*SCALING_FACTOR);
|
||||
|
||||
// write the tranformation data into the model instance
|
||||
inst_ptr->rotation = rot;
|
||||
inst_ptr->offset = foff;
|
||||
inst_ptr->offset_z = -batch_offset;
|
||||
}
|
||||
};
|
||||
|
||||
std::cout << "Applying result..." << std::endl;
|
||||
bench.start();
|
||||
// std::cout << "Applying result..." << std::endl;
|
||||
// bench.start();
|
||||
if(first_bin_only) {
|
||||
applyResult(result.front(), 0);
|
||||
} else {
|
||||
|
||||
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;
|
||||
|
||||
for(auto& group : result) {
|
||||
|
@ -539,9 +536,9 @@ bool arrange(Model &model, coordf_t dist, const Slic3r::BoundingBoxf* bb,
|
|||
batch_offset += stride;
|
||||
}
|
||||
}
|
||||
bench.stop();
|
||||
std::cout << "Result applied in " << bench.getElapsedSec()
|
||||
<< " seconds." << std::endl;
|
||||
// bench.stop();
|
||||
// std::cout << "Result applied in " << bench.getElapsedSec()
|
||||
// << " seconds." << std::endl;
|
||||
|
||||
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;
|
||||
if(bb != nullptr && bb->defined) {
|
||||
const bool FIRST_BIN_ONLY = false;
|
||||
ret = arr::arrange(*this, dist, bb, FIRST_BIN_ONLY, progressind);
|
||||
ret = arr::arrange(*this, dist, bb, false, progressind);
|
||||
} else {
|
||||
// get the (transformed) size of each instance so that we take
|
||||
// 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->scale(this->scaling_factor); // scale around mesh origin
|
||||
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
|
||||
|
|
|
@ -206,7 +206,6 @@ public:
|
|||
double rotation; // Rotation around the Z axis, in radians around mesh center point
|
||||
double scaling_factor;
|
||||
Pointf offset; // in unscaled coordinates
|
||||
double offset_z = 0;
|
||||
|
||||
ModelObject* get_object() const { return this->object; }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "AppController.hpp"
|
||||
|
||||
#include <future>
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <cstdarg>
|
||||
#include <thread>
|
||||
|
@ -9,6 +10,7 @@
|
|||
#include <slic3r/GUI/GUI.hpp>
|
||||
#include <slic3r/GUI/PresetBundle.hpp>
|
||||
|
||||
#include <Geometry.hpp>
|
||||
#include <PrintConfig.hpp>
|
||||
#include <Print.hpp>
|
||||
#include <Model.hpp>
|
||||
|
@ -58,14 +60,18 @@ void AppControllerBoilerplate::progress_indicator(
|
|||
progressind_->m.unlock();
|
||||
}
|
||||
|
||||
void AppControllerBoilerplate::progress_indicator(unsigned statenum,
|
||||
const std::string &title,
|
||||
const std::string &firstmsg)
|
||||
AppControllerBoilerplate::ProgresIndicatorPtr
|
||||
AppControllerBoilerplate::progress_indicator(
|
||||
unsigned statenum,
|
||||
const std::string &title,
|
||||
const std::string &firstmsg)
|
||||
{
|
||||
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);;
|
||||
progressind_->m.unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AppControllerBoilerplate::ProgresIndicatorPtr
|
||||
|
@ -266,6 +272,11 @@ void PrintController::slice()
|
|||
Slic3r::trace(3, "Slicing process finished.");
|
||||
}
|
||||
|
||||
const PrintConfig &PrintController::config() const
|
||||
{
|
||||
return print_->config;
|
||||
}
|
||||
|
||||
void IProgressIndicator::message_fmt(
|
||||
const std::string &fmtstr, ...) {
|
||||
std::stringstream ss;
|
||||
|
@ -295,19 +306,46 @@ void IProgressIndicator::message_fmt(
|
|||
|
||||
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]()
|
||||
{
|
||||
// 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);
|
||||
// my $success = $self->{model}->arrange_objects(wxTheApp->{preset_bundle}->full_config->min_object_distance, $bb);
|
||||
// double dist = GUI::get_preset_bundle()->full_config().option("min_object_distance")->getFloat();
|
||||
auto pind = progress_indicator();
|
||||
auto pmax = pind->max();
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Slic3r {
|
|||
class Model;
|
||||
class Print;
|
||||
class PrintObject;
|
||||
class PrintConfig;
|
||||
|
||||
/**
|
||||
* @brief A boilerplate class for creating application logic. It should provide
|
||||
|
@ -108,9 +109,9 @@ public:
|
|||
* @param title The title of the procedure.
|
||||
* @param firstmsg The message for the first subtask to be displayed.
|
||||
*/
|
||||
void progress_indicator(unsigned statenum,
|
||||
const std::string& title,
|
||||
const std::string& firstmsg = "");
|
||||
ProgresIndicatorPtr progress_indicator(unsigned statenum,
|
||||
const std::string& title,
|
||||
const std::string& firstmsg = "");
|
||||
|
||||
/**
|
||||
* @brief Return the progress indicator set up for the current thread. This
|
||||
|
@ -147,6 +148,8 @@ public:
|
|||
*/
|
||||
bool supports_asynch() const;
|
||||
|
||||
void process_events();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -205,6 +208,8 @@ public:
|
|||
* @brief Slice the loaded print scene.
|
||||
*/
|
||||
void slice();
|
||||
|
||||
const PrintConfig& config() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,11 @@ bool AppControllerBoilerplate::supports_asynch() const
|
|||
return true;
|
||||
}
|
||||
|
||||
void AppControllerBoilerplate::process_events()
|
||||
{
|
||||
wxSafeYield();
|
||||
}
|
||||
|
||||
AppControllerBoilerplate::PathList
|
||||
AppControllerBoilerplate::query_destination_paths(
|
||||
const std::string &title,
|
||||
|
@ -79,7 +84,7 @@ bool AppControllerBoilerplate::report_issue(IssueType issuetype,
|
|||
case IssueType::FATAL: icon = wxICON_ERROR;
|
||||
}
|
||||
|
||||
auto ret = wxMessageBox(description, brief, icon | style);
|
||||
auto ret = wxMessageBox(_(description), _(brief), icon | style);
|
||||
return ret != wxCANCEL;
|
||||
}
|
||||
|
||||
|
@ -216,7 +221,7 @@ class Wrapper: public IProgressIndicator, public wxEvtHandler {
|
|||
}
|
||||
|
||||
void _state(unsigned st) {
|
||||
if( st <= max() ) {
|
||||
if( st <= IProgressIndicator::max() ) {
|
||||
Base::state(st);
|
||||
|
||||
if(!gauge_->IsShown()) showProgress(true);
|
||||
|
@ -253,7 +258,14 @@ public:
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -261,7 +273,9 @@ public:
|
|||
auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
|
||||
evt->SetInt(st);
|
||||
wxQueueEvent(this, evt);
|
||||
} else _state(st);
|
||||
} else {
|
||||
_state(st);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void message(const std::string & msg) override {
|
||||
|
|
Loading…
Reference in a new issue