|
@@ -328,198 +328,6 @@ double Print::max_allowed_layer_height() const
|
|
|
return nozzle_diameter_max;
|
|
|
}
|
|
|
|
|
|
-// Caller is responsible for supplying models whose objects don't collide
|
|
|
-// and have explicit instance positions.
|
|
|
-void Print::add_model_object_perl_tests_only(ModelObject* model_object, int idx)
|
|
|
-{
|
|
|
- tbb::mutex::scoped_lock lock(this->state_mutex());
|
|
|
- // Add a copy of this ModelObject to this Print.
|
|
|
- m_model.objects.emplace_back(ModelObject::new_copy(*model_object));
|
|
|
- m_model.objects.back()->set_model(&m_model);
|
|
|
- // Initialize a new print object and store it at the given position.
|
|
|
- PrintObject *object = new PrintObject(this, model_object, true);
|
|
|
- if (idx != -1) {
|
|
|
- delete m_objects[idx];
|
|
|
- m_objects[idx] = object;
|
|
|
- } else
|
|
|
- m_objects.emplace_back(object);
|
|
|
- // Invalidate all print steps.
|
|
|
- this->invalidate_all_steps();
|
|
|
-
|
|
|
- // Set the transformation matrix without translation from the first instance.
|
|
|
- if (! model_object->instances.empty()) {
|
|
|
- // Trafo and bounding box, both in world coordinate system.
|
|
|
- Transform3d trafo = model_object->instances.front()->get_matrix();
|
|
|
- BoundingBoxf3 bbox = model_object->instance_bounding_box(0);
|
|
|
- // Now shift the object up to align it with the print bed.
|
|
|
- trafo.data()[14] -= bbox.min(2);
|
|
|
- // and reset the XY translation.
|
|
|
- trafo.data()[12] = 0;
|
|
|
- trafo.data()[13] = 0;
|
|
|
- object->set_trafo(trafo);
|
|
|
- }
|
|
|
-
|
|
|
- int volume_id = 0;
|
|
|
- for (const ModelVolume *volume : model_object->volumes) {
|
|
|
- if (! volume->is_model_part() && ! volume->is_modifier())
|
|
|
- continue;
|
|
|
- // Get the config applied to this volume.
|
|
|
- PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, nullptr, *volume, 99999);
|
|
|
- // Find an existing print region with the same config.
|
|
|
- int region_id = -1;
|
|
|
- for (int i = 0; i < (int)m_regions.size(); ++ i)
|
|
|
- if (config.equals(m_regions[i]->config())) {
|
|
|
- region_id = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- // If no region exists with the same config, create a new one.
|
|
|
- if (region_id == -1) {
|
|
|
- region_id = (int)m_regions.size();
|
|
|
- this->add_region(config);
|
|
|
- }
|
|
|
- // Assign volume to a region.
|
|
|
- object->add_region_volume((unsigned int)region_id, volume_id, t_layer_height_range(0, DBL_MAX));
|
|
|
- ++ volume_id;
|
|
|
- }
|
|
|
-
|
|
|
- // Apply config to print object.
|
|
|
- object->config_apply(this->default_object_config());
|
|
|
- {
|
|
|
- //normalize_and_apply_config(object->config(), model_object->config);
|
|
|
- DynamicPrintConfig src_normalized(model_object->config);
|
|
|
- src_normalized.normalize();
|
|
|
- object->config_apply(src_normalized, true);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// This function is only called through the Perl-C++ binding from the unit tests, should be
|
|
|
-// removed when unit tests are rewritten to C++.
|
|
|
-bool Print::apply_config_perl_tests_only(DynamicPrintConfig config)
|
|
|
-{
|
|
|
- tbb::mutex::scoped_lock lock(this->state_mutex());
|
|
|
-
|
|
|
-
|
|
|
- // Perl unit tests were failing in case the preset was not normalized (e.g. https://github.com/prusa3d/PrusaSlicer/issues/2288 was caused
|
|
|
- // by too short max_layer_height vector. Calling the necessary function Preset::normalize(...) is not currently possible because there is no
|
|
|
- // access to preset. This should be solved when the unit tests are rewritten to C++. For now we just copy-pasted code from Preset.cpp
|
|
|
- // to make sure the unit tests pass (functions set_num_extruders and nozzle_options()).
|
|
|
- auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter", true));
|
|
|
- assert(nozzle_diameter != nullptr);
|
|
|
- const auto &defaults = FullPrintConfig::defaults();
|
|
|
- for (const std::string &key : { "nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
|
|
|
- "retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
|
|
|
- "retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
|
|
|
- "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour" })
|
|
|
- {
|
|
|
- auto *opt = config.option(key, true);
|
|
|
- assert(opt != nullptr);
|
|
|
- assert(opt->is_vector());
|
|
|
- unsigned int num_extruders = (unsigned int)nozzle_diameter->values.size();
|
|
|
- static_cast<ConfigOptionVectorBase*>(opt)->resize(num_extruders, defaults.option(key));
|
|
|
- }
|
|
|
-
|
|
|
- // we get a copy of the config object so we can modify it safely
|
|
|
- config.normalize();
|
|
|
-
|
|
|
- // apply variables to placeholder parser
|
|
|
- this->placeholder_parser().apply_config(config);
|
|
|
-
|
|
|
- // handle changes to print config
|
|
|
- t_config_option_keys print_diff = m_config.diff(config);
|
|
|
- m_config.apply_only(config, print_diff, true);
|
|
|
- bool invalidated = this->invalidate_state_by_config_options(print_diff);
|
|
|
-
|
|
|
- // handle changes to object config defaults
|
|
|
- m_default_object_config.apply(config, true);
|
|
|
- for (PrintObject *object : m_objects) {
|
|
|
- // we don't assume that config contains a full ObjectConfig,
|
|
|
- // so we base it on the current print-wise default
|
|
|
- PrintObjectConfig new_config = this->default_object_config();
|
|
|
- // we override the new config with object-specific options
|
|
|
- normalize_and_apply_config(new_config, object->model_object()->config);
|
|
|
- // check whether the new config is different from the current one
|
|
|
- t_config_option_keys diff = object->config().diff(new_config);
|
|
|
- object->config_apply_only(new_config, diff, true);
|
|
|
- invalidated |= object->invalidate_state_by_config_options(diff);
|
|
|
- }
|
|
|
-
|
|
|
- // handle changes to regions config defaults
|
|
|
- m_default_region_config.apply(config, true);
|
|
|
-
|
|
|
- // All regions now have distinct settings.
|
|
|
- // Check whether applying the new region config defaults we'd get different regions.
|
|
|
- bool rearrange_regions = false;
|
|
|
- {
|
|
|
- // Collect the already visited region configs into other_region_configs,
|
|
|
- // so one may check for duplicates.
|
|
|
- std::vector<PrintRegionConfig> other_region_configs;
|
|
|
- for (size_t region_id = 0; region_id < m_regions.size(); ++ region_id) {
|
|
|
- PrintRegion ®ion = *m_regions[region_id];
|
|
|
- PrintRegionConfig this_region_config;
|
|
|
- bool this_region_config_set = false;
|
|
|
- for (PrintObject *object : m_objects) {
|
|
|
- if (region_id < object->region_volumes.size()) {
|
|
|
- for (const std::pair<t_layer_height_range, int> &volume_and_range : object->region_volumes[region_id]) {
|
|
|
- const ModelVolume &volume = *object->model_object()->volumes[volume_and_range.second];
|
|
|
- if (this_region_config_set) {
|
|
|
- // If the new config for this volume differs from the other
|
|
|
- // volume configs currently associated to this region, it means
|
|
|
- // the region subdivision does not make sense anymore.
|
|
|
- if (! this_region_config.equals(PrintObject::region_config_from_model_volume(m_default_region_config, nullptr, volume, 99999))) {
|
|
|
- rearrange_regions = true;
|
|
|
- goto exit_for_rearrange_regions;
|
|
|
- }
|
|
|
- } else {
|
|
|
- this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, nullptr, volume, 99999);
|
|
|
- this_region_config_set = true;
|
|
|
- }
|
|
|
- for (const PrintRegionConfig &cfg : other_region_configs) {
|
|
|
- // If the new config for this volume equals any of the other
|
|
|
- // volume configs that are not currently associated to this
|
|
|
- // region, it means the region subdivision does not make
|
|
|
- // sense anymore.
|
|
|
- if (cfg.equals(this_region_config)) {
|
|
|
- rearrange_regions = true;
|
|
|
- goto exit_for_rearrange_regions;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (this_region_config_set) {
|
|
|
- t_config_option_keys diff = region.config().diff(this_region_config);
|
|
|
- if (! diff.empty()) {
|
|
|
- region.config_apply_only(this_region_config, diff, false);
|
|
|
- for (PrintObject *object : m_objects)
|
|
|
- if (region_id < object->region_volumes.size() && ! object->region_volumes[region_id].empty())
|
|
|
- invalidated |= object->invalidate_state_by_config_options(diff);
|
|
|
- }
|
|
|
- other_region_configs.emplace_back(std::move(this_region_config));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-exit_for_rearrange_regions:
|
|
|
-
|
|
|
- if (rearrange_regions) {
|
|
|
- // The current subdivision of regions does not make sense anymore.
|
|
|
- // We need to remove all objects and re-add them.
|
|
|
- ModelObjectPtrs model_objects;
|
|
|
- model_objects.reserve(m_objects.size());
|
|
|
- for (PrintObject *object : m_objects)
|
|
|
- model_objects.push_back(object->model_object());
|
|
|
- this->clear();
|
|
|
- for (ModelObject *mo : model_objects)
|
|
|
- this->add_model_object_perl_tests_only(mo);
|
|
|
- invalidated = true;
|
|
|
- }
|
|
|
-
|
|
|
- for (PrintObject *object : m_objects)
|
|
|
- object->update_slicing_parameters();
|
|
|
-
|
|
|
- return invalidated;
|
|
|
-}
|
|
|
-
|
|
|
// Add or remove support modifier ModelVolumes from model_object_dst to match the ModelVolumes of model_object_new
|
|
|
// in the exact order and with the same IDs.
|
|
|
// It is expected, that the model_object_dst already contains the non-support volumes of model_object_new in the correct order.
|
|
@@ -1247,7 +1055,7 @@ std::string Print::validate() const
|
|
|
Geometry::assemble_transform(Vec3d::Zero(), rotation, model_instance0->get_scaling_factor(), model_instance0->get_mirror())),
|
|
|
float(scale_(0.5 * m_config.extruder_clearance_radius.value)), jtRound, float(scale_(0.1))).front();
|
|
|
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
|
|
|
- for (const Point © : print_object->m_copies) {
|
|
|
+ for (const Point © : print_object->copies()) {
|
|
|
Polygon convex_hull = convex_hull0;
|
|
|
convex_hull.translate(copy);
|
|
|
if (! intersection(convex_hulls_other, convex_hull).empty())
|