WIP: Reconstruction of background processing.

This commit is contained in:
bubnikv 2018-10-23 15:27:31 +02:00
parent f33713e060
commit bded28f888
17 changed files with 273 additions and 229 deletions

View file

@ -242,6 +242,14 @@ BoundingBoxf3 Model::bounding_box() const
return bb;
}
unsigned int Model::update_print_volume_state(const BoundingBoxf3 &print_volume)
{
unsigned int num_printable = 0;
for (ModelObject *model_object : this->objects)
num_printable += model_object->check_instances_print_volume_state(print_volume);
return num_printable;
}
void Model::center_instances_around_point(const Vec2d &point)
{
BoundingBoxf3 bb;
@ -875,26 +883,32 @@ void ModelObject::repair()
v->mesh.repair();
}
// Called by Print::validate() from the UI thread.
void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
unsigned int ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
{
for (const ModelVolume* vol : this->volumes)
{
if (vol->is_model_part())
{
for (ModelInstance* inst : this->instances)
{
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(inst->world_matrix());
unsigned int num_printable = 0;
enum {
INSIDE = 1,
OUTSIDE = 2
};
for (ModelInstance *model_instance : this->instances) {
unsigned int inside_outside = 0;
for (const ModelVolume *vol : this->volumes)
if (vol->is_model_part()) {
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(model_instance->world_matrix());
if (print_volume.contains(bb))
inst->print_volume_state = ModelInstance::PVS_Inside;
inside_outside |= INSIDE;
else if (print_volume.intersects(bb))
inst->print_volume_state = ModelInstance::PVS_Partly_Outside;
inside_outside |= INSIDE | OUTSIDE;
else
inst->print_volume_state = ModelInstance::PVS_Fully_Outside;
inside_outside |= OUTSIDE;
}
}
model_instance->print_volume_state =
(inside_outside == (INSIDE | OUTSIDE)) ? ModelInstance::PVS_Partly_Outside :
(inside_outside == INSIDE) ? ModelInstance::PVS_Inside : ModelInstance::PVS_Fully_Outside;
if (inside_outside == INSIDE)
++ num_printable;
}
return num_printable;
}
void ModelObject::print_info() const

View file

@ -156,7 +156,7 @@ public:
void repair();
// Called by Print::validate() from the UI thread.
void check_instances_print_volume_state(const BoundingBoxf3& print_volume);
unsigned int check_instances_print_volume_state(const BoundingBoxf3& print_volume);
// Print object statistics to console.
void print_info() const;
@ -411,6 +411,9 @@ public:
bool add_default_instances();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
// Set the print_volume_state of PrintObject::instances,
// return total number of printable objects.
unsigned int update_print_volume_state(const BoundingBoxf3 &print_volume);
void center_instances_around_point(const Vec2d &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;

View file

@ -852,7 +852,11 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config_in)
bool modifiers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::PARAMETER_MODIFIER);
bool support_blockers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::SUPPORT_BLOCKER);
bool support_enforcers_differ = model_volume_list_changed(model_object, model_object_new, ModelVolume::SUPPORT_ENFORCER);
if (model_parts_differ || modifiers_differ) {
if (model_parts_differ || modifiers_differ ||
model_object.origin_translation != model_object_new.origin_translation ||
model_object.layer_height_ranges != model_object_new.layer_height_ranges ||
model_object.layer_height_profile != model_object_new.layer_height_profile ||
model_object.layer_height_profile_valid != model_object_new.layer_height_profile_valid) {
// The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects.
auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id()));
for (auto it = range.first; it != range.second; ++ it) {
@ -889,6 +893,9 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config_in)
it->print_object->config_apply_only(new_config, diff, true);
}
}
model_object.name = model_object_new.name;
model_object.input_file = model_object_new.input_file;
model_object.instances = model_object_new.instances;
}
}
@ -936,11 +943,10 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config_in)
print_objects_new.emplace_back(print_object);
print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New));
} else if ((*it_old)->print_object->copies() != new_instances.copies) {
// The PrintObject already exists and the copies differ. The only step currently sensitive to the order is the G-code generator.
// Stop it.
this->invalidate_step(psGCodeExport);
// The PrintObject already exists and the copies differ.
(*it_old)->print_object->set_copies(new_instances.copies);
}
print_objects_new.emplace_back((*it_old)->print_object);
}
}
}
if (m_objects != print_objects_new) {
@ -958,7 +964,7 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config_in)
int idx_region = 0;
for (const auto &volumes : print_object->region_volumes) {
if (! volumes.empty())
++ m_regions[idx_region];
++ m_regions[idx_region]->m_refcnt;
++ idx_region;
}
}
@ -1110,23 +1116,7 @@ bool Print::has_skirt() const
std::string Print::validate() const
{
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(m_config.bed_shape.values));
BoundingBoxf3 print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(m_config.max_print_height)));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
print_volume.min(2) = -1e10;
unsigned int printable_count = 0;
{
// Lock due to the po->reload_model_instances()
tbb::mutex::scoped_lock lock(m_mutex);
for (PrintObject *po : m_objects) {
po->model_object()->check_instances_print_volume_state(print_volume);
po->reload_model_instances();
if (po->is_printable())
++ printable_count;
}
}
if (printable_count == 0)
if (m_objects.empty())
return L("All objects are outside of the print volume.");
if (m_config.complete_objects) {

View file

@ -96,6 +96,7 @@ public:
#endif
mtx.unlock();
cancel();
m_state[step] = INVALID;
mtx.lock();
}
return invalidated;

View file

@ -87,23 +87,25 @@ bool PrintObject::delete_last_copy()
bool PrintObject::set_copies(const Points &points)
{
bool copies_num_changed = m_copies.size() != points.size();
// order copies with a nearest neighbor search and translate them by _copies_shift
m_copies.clear();
m_copies.reserve(points.size());
// order copies with a nearest-neighbor search
std::vector<Points::size_type> ordered_copies;
Slic3r::Geometry::chained_path(points, ordered_copies);
for (size_t point_idx : ordered_copies)
m_copies.push_back(points[point_idx] + m_copies_shift);
bool invalidated = m_print->invalidate_step(psSkirt);
invalidated |= m_print->invalidate_step(psBrim);
if (copies_num_changed)
invalidated |= m_print->invalidate_step(psWipeTower);
// Order copies with a nearest-neighbor search.
std::vector<Point> copies;
{
std::vector<Points::size_type> ordered_copies;
Slic3r::Geometry::chained_path(points, ordered_copies);
copies.reserve(ordered_copies.size());
for (size_t point_idx : ordered_copies)
copies.emplace_back(points[point_idx] + m_copies_shift);
}
// Invalidate and set copies.
bool invalidated = false;
if (copies != m_copies) {
invalidated = m_print->invalidate_step(psSkirt);
invalidated |= m_print->invalidate_step(psBrim);
if (copies.size() != m_copies.size())
invalidated |= m_print->invalidate_step(psWipeTower);
invalidated |= m_print->invalidate_step(psGCodeExport);
m_copies = copies;
}
return invalidated;
}

View file

@ -858,12 +858,12 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
// find layer extents
std::vector<float>::const_iterator min_layer, max_layer;
min_layer = std::lower_bound(z.begin(), z.end(), min_z); // first layer whose slice_z is >= min_z
max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z) - 1; // last layer whose slice_z is <= max_z
max_layer = std::upper_bound(z.begin() + (min_layer - z.begin()), z.end(), max_z); // first layer, whose slice_z is > max_z
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
printf("layers: min = %d, max = %d\n", (int)(min_layer - z.begin()), (int)(max_layer - z.begin()));
printf("layers: min = %d, max = %d\n", (int)(min_layer - z.begin()), (int)(max_layer - z.begin()) - 1);
#endif /* SLIC3R_TRIANGLEMESH_DEBUG */
for (std::vector<float>::const_iterator it = min_layer; it != max_layer + 1; ++it) {
for (std::vector<float>::const_iterator it = min_layer; it != max_layer; ++it) {
std::vector<float>::size_type layer_idx = it - z.begin();
IntersectionLine il;
if (this->slice_facet(*it / SCALING_FACTOR, facet, facet_idx, min_z, max_z, &il) == TriangleMeshSlicer::Slicing) {