diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index e68eb7b6d..50047b6cb 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -2090,31 +2090,50 @@ bool model_volume_list_changed(const ModelObject &model_object_old, const ModelO }); } +template< typename TypeFilterFn, typename CompareFn> +bool model_property_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, typename TypeFilterFn type_filter, typename CompareFn compare) +{ + assert(! model_volume_list_changed(model_object_old, model_object_new, type_filter)); + size_t i_old, i_new; + for (i_old = 0, i_new = 0; i_old < model_object_old.volumes.size() && i_new < model_object_new.volumes.size();) { + const ModelVolume &mv_old = *model_object_old.volumes[i_old]; + const ModelVolume &mv_new = *model_object_new.volumes[i_new]; + if (! type_filter(mv_old.type())) { + ++ i_old; + continue; + } + if (! type_filter(mv_new.type())) { + ++ i_new; + continue; + } + assert(mv_old.type() == mv_new.type() && mv_old.id() == mv_new.id()); + if (! compare(mv_old, mv_new)) + return true; + ++ i_old; + ++ i_new; + } + return false; +} + bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART)); - for (size_t i = 0; i < mo.volumes.size(); ++ i) - if (! mo_new.volumes[i]->supported_facets.timestamp_matches(mo.volumes[i]->supported_facets)) - return true; - return false; + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.supported_facets.timestamp_matches(mv_new.supported_facets); }); } bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART)); - for (size_t i = 0; i < mo.volumes.size(); ++ i) - if (! mo_new.volumes[i]->seam_facets.timestamp_matches(mo.volumes[i]->seam_facets)) - return true; - return false; + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.seam_facets.timestamp_matches(mv_new.seam_facets); }); } bool model_mmu_segmentation_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - assert(! model_volume_list_changed(mo, mo_new, ModelVolumeType::MODEL_PART)); - for (size_t i = 0; i < mo.volumes.size(); ++ i) - if (! mo_new.volumes[i]->mmu_segmentation_facets.timestamp_matches(mo.volumes[i]->mmu_segmentation_facets)) - return true; - return false; + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.mmu_segmentation_facets.timestamp_matches(mv_new.mmu_segmentation_facets); }); } bool model_has_multi_part_objects(const Model &model) diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 0fe2c5b29..8803c95df 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -347,12 +347,12 @@ struct ModelObjectStatus { struct ModelObjectStatusDB { void add(const ModelObject &model_object, const ModelObjectStatus::Status status) { + assert(db.find(ModelObjectStatus(model_object.id())) == db.end()); db.emplace(model_object.id(), status); } bool add_if_new(const ModelObject &model_object, const ModelObjectStatus::Status status) { auto it = db.find(ModelObjectStatus(model_object.id())); - assert(it != db.end()); if (it == db.end()) { db.emplace_hint(it, model_object.id(), status); return true; @@ -1057,10 +1057,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ assert(model_object_status.status == ModelObjectStatus::Old || model_object_status.status == ModelObjectStatus::Moved); // Check whether a model part volume was added or removed, their transformations or order changed. // Only volume IDs, volume types, transformation matrices and their order are checked, configuration and other parameters are NOT checked. - bool solid_or_modifier_differ = model_volume_list_changed(model_object, model_object_new, solid_or_modifier_types); + bool solid_or_modifier_differ = model_volume_list_changed(model_object, model_object_new, solid_or_modifier_types) || + model_mmu_segmentation_data_changed(model_object, model_object_new); bool supports_differ = model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_BLOCKER) || model_volume_list_changed(model_object, model_object_new, ModelVolumeType::SUPPORT_ENFORCER); - bool mmu_segmentation_differ = model_mmu_segmentation_data_changed(model_object, model_object_new); bool layer_height_ranges_differ = ! layer_height_ranges_equal(model_object.layer_config_ranges, model_object_new.layer_config_ranges, model_object_new.layer_height_profile.empty()); bool model_origin_translation_differ = model_object.origin_translation != model_object_new.origin_translation; auto print_objects_range = print_object_status_db.get_range(model_object); @@ -1068,7 +1068,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // All PrintObjects in print_objects_range shall point to the same prints_objects_regions model_object_status.print_object_regions = print_objects_range.begin()->print_object->m_shared_regions; model_object_status.print_object_regions->ref_cnt_inc(); - if (solid_or_modifier_differ || mmu_segmentation_differ || model_origin_translation_differ || layer_height_ranges_differ || + if (solid_or_modifier_differ || model_origin_translation_differ || layer_height_ranges_differ || ! model_object.layer_height_profile.timestamp_matches(model_object_new.layer_height_profile)) { // The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects. model_object_status.print_object_regions_status = model_origin_translation_differ || layer_height_ranges_differ ? diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index b46ef36b1..b83eaed66 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -818,9 +818,12 @@ std::vector PrintObject::slice_support_volumes(const ModelVolumeType bool merge = false; const Print *print = this->print(); auto throw_on_cancel_callback = std::function([print](){ print->throw_if_canceled(); }); + MeshSlicingParamsEx params; + params.trafo = this->trafo(); + params.trafo.pretranslate(Vec3d(-unscale(m_center_offset.x()), -unscale(m_center_offset.y()), 0)); for (; it_volume != it_volume_end; ++ it_volume) if ((*it_volume)->type() == model_volume_type) { - std::vector slices2 = slice_volume(*(*it_volume), zs, MeshSlicingParamsEx{}, throw_on_cancel_callback); + std::vector slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback); if (slices.empty()) slices = std::move(slices2); else if (! slices2.empty()) {