mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	WIP: Synchronization of Model / ModelObject with Print / PrintObject
This commit is contained in:
		
							parent
							
								
									7ed2752b2b
								
							
						
					
					
						commit
						bb1dfa3522
					
				
					 2 changed files with 228 additions and 126 deletions
				
			
		|  | @ -376,6 +376,16 @@ double Print::max_allowed_layer_height() const | |||
|     return nozzle_diameter_max; | ||||
| } | ||||
| 
 | ||||
| static PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_region_config, const ModelVolume &volume) | ||||
| { | ||||
|     PrintRegionConfig config = default_region_config; | ||||
|     normalize_and_apply_config(config, volume.get_object()->config); | ||||
|     normalize_and_apply_config(config, volume.config); | ||||
|     if (! volume.material_id().empty()) | ||||
|         normalize_and_apply_config(config, volume.material()->config); | ||||
|     return config; | ||||
| } | ||||
| 
 | ||||
| // Caller is responsible for supplying models whose objects don't collide
 | ||||
| // and have explicit instance positions.
 | ||||
| void Print::add_model_object(ModelObject* model_object, int idx) | ||||
|  | @ -397,7 +407,7 @@ void Print::add_model_object(ModelObject* model_object, int idx) | |||
|         if (! volume->is_model_part() && ! volume->is_modifier()) | ||||
|             continue; | ||||
|         // Get the config applied to this volume.
 | ||||
|         PrintRegionConfig config = this->_region_config_from_model_volume(*volume); | ||||
|         PrintRegionConfig config = region_config_from_model_volume(m_default_region_config, *volume); | ||||
|         // Find an existing print region with the same config.
 | ||||
|         size_t region_id = size_t(-1); | ||||
|         for (size_t i = 0; i < m_regions.size(); ++ i) | ||||
|  | @ -424,35 +434,7 @@ void Print::add_model_object(ModelObject* model_object, int idx) | |||
|         object->config_apply(src_normalized, true); | ||||
|     } | ||||
|      | ||||
|     // update placeholders
 | ||||
|     { | ||||
|         // get the first input file name
 | ||||
|         std::string input_file; | ||||
|         std::vector<std::string> v_scale; | ||||
|         for (const PrintObject *object : m_objects) { | ||||
|             const ModelObject &mobj = *object->model_object(); | ||||
| #if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM | ||||
|             // CHECK_ME -> Is the following correct ?
 | ||||
|             v_scale.push_back("x:" + boost::lexical_cast<std::string>(mobj.instances[0]->get_scaling_factor(X) * 100) + | ||||
|                 "% y:" + boost::lexical_cast<std::string>(mobj.instances[0]->get_scaling_factor(Y) * 100) + | ||||
|                 "% z:" + boost::lexical_cast<std::string>(mobj.instances[0]->get_scaling_factor(Z) * 100) + "%"); | ||||
| #else | ||||
|             v_scale.push_back(boost::lexical_cast<std::string>(mobj.instances[0]->scaling_factor * 100) + "%"); | ||||
| #endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
 | ||||
|             if (input_file.empty()) | ||||
|                 input_file = mobj.input_file; | ||||
|         } | ||||
|          | ||||
|         PlaceholderParser &pp = m_placeholder_parser; | ||||
|         pp.set("scale", v_scale); | ||||
|         if (! input_file.empty()) { | ||||
|             // get basename with and without suffix
 | ||||
|             const std::string input_basename = boost::filesystem::path(input_file).filename().string(); | ||||
|             pp.set("input_filename", input_basename); | ||||
|             const std::string input_basename_base = input_basename.substr(0, input_basename.find_last_of(".")); | ||||
|             pp.set("input_filename_base", input_basename_base); | ||||
|         } | ||||
|     } | ||||
|     this->update_object_placeholders(); | ||||
| } | ||||
| 
 | ||||
| bool Print::apply_config(DynamicPrintConfig config) | ||||
|  | @ -514,12 +496,12 @@ bool Print::apply_config(DynamicPrintConfig config) | |||
|                             // 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(this->_region_config_from_model_volume(volume))) { | ||||
|                             if (! this_region_config.equals(region_config_from_model_volume(m_default_region_config, volume))) { | ||||
|                                 rearrange_regions = true; | ||||
|                                 goto exit_for_rearrange_regions; | ||||
|                             } | ||||
|                         } else { | ||||
|                             this_region_config = this->_region_config_from_model_volume(volume); | ||||
|                             this_region_config = region_config_from_model_volume(m_default_region_config, volume); | ||||
|                             this_region_config_set = true; | ||||
|                         } | ||||
|                         for (const PrintRegionConfig &cfg : other_region_configs) { | ||||
|  | @ -681,7 +663,7 @@ static inline bool transform3d_equal(const Transform3d &lhs, const Transform3d & | |||
| struct PrintInstances | ||||
| { | ||||
|     Transform3d     trafo; | ||||
|     Points          instances; | ||||
|     Points          copies; | ||||
|     bool operator<(const PrintInstances &rhs) const { return transform3d_lower(this->trafo, rhs.trafo); } | ||||
| }; | ||||
| 
 | ||||
|  | @ -690,26 +672,46 @@ static std::vector<PrintInstances> print_objects_from_model_object(const ModelOb | |||
| { | ||||
|     std::set<PrintInstances> trafos; | ||||
|     PrintInstances           trafo; | ||||
|     trafo.instances.assign(1, Point()); | ||||
|     trafo.copies.assign(1, Point()); | ||||
|     for (ModelInstance *model_instance : model_object.instances) | ||||
|         if (model_instance->is_printable()) { | ||||
|             const Vec3d &offst = model_instance->get_offset(); | ||||
|             trafo.trafo = model_instance->world_matrix(true); | ||||
|             trafo.instances.front() = Point::new_scale(offst(0), offst(1)); | ||||
|             trafo.copies.front() = Point::new_scale(offst(0), offst(1)); | ||||
|             auto it = trafos.find(trafo); | ||||
|             if (it == trafos.end()) | ||||
|                 trafos.emplace(trafo); | ||||
|             else | ||||
|                 const_cast<PrintInstances&>(*it).instances.emplace_back(trafo.instances.front()); | ||||
|                 const_cast<PrintInstances&>(*it).copies.emplace_back(trafo.copies.front()); | ||||
|         } | ||||
|     return std::vector<PrintInstances>(trafos.begin(), trafos.end()); | ||||
| } | ||||
| 
 | ||||
| bool Print::apply(const Model &model, const DynamicPrintConfig &config) | ||||
| bool Print::apply(const Model &model, const DynamicPrintConfig &config_in) | ||||
| { | ||||
|     // Make a copy of the config, normalize it.
 | ||||
|     DynamicPrintConfig config(config_in); | ||||
|     config.normalize(); | ||||
|     // Collect changes to print config.
 | ||||
|     t_config_option_keys print_diff  = m_config.diff(config); | ||||
|     t_config_option_keys object_diff = m_default_object_config.diff(config); | ||||
|     t_config_option_keys region_diff = m_default_region_config.diff(config); | ||||
| 
 | ||||
|     // Grab the lock for the Print / PrintObject milestones.
 | ||||
|     tbb::mutex::scoped_lock lock(m_mutex); | ||||
| 
 | ||||
|     // The following call may stop the background processing.
 | ||||
|     bool invalidated = this->invalidate_state_by_config_options(print_diff); | ||||
|     // Apply variables to placeholder parser. The placeholder parser is used by G-code export,
 | ||||
|     // which should be stopped if print_diff is not empty.
 | ||||
|     m_placeholder_parser.apply_config(config); | ||||
|     // It is also safe to change m_config now after this->invalidate_state_by_config_options() call.
 | ||||
|     m_config.apply_only(config, print_diff, true); | ||||
|     // Handle changes to object config defaults
 | ||||
|     m_default_object_config.apply_only(config, object_diff, true); | ||||
|     // Handle changes to regions config defaults
 | ||||
|     m_default_region_config.apply_only(config, region_diff, true); | ||||
|      | ||||
|     struct ModelObjectStatus { | ||||
|         enum Status { | ||||
|             Unknown, | ||||
|  | @ -719,8 +721,9 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|             Deleted, | ||||
|         }; | ||||
|         ModelObjectStatus(ModelID id, Status status = Unknown) : id(id), status(status) {} | ||||
|         ModelID id; | ||||
|         Status status; | ||||
|         ModelID                 id; | ||||
|         Status                  status; | ||||
|         t_config_option_keys    object_config_diff; | ||||
|         // Search by id.
 | ||||
|         bool operator<(const ModelObjectStatus &rhs) const { return id < rhs.id; } | ||||
|     }; | ||||
|  | @ -729,7 +732,8 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|     // 1) Synchronize model objects.
 | ||||
|     if (model.id() != m_model.id()) { | ||||
|         // Kill everything, initialize from scratch.
 | ||||
|         // The following call shall kill any computation if running.
 | ||||
|         // Stop background processing.
 | ||||
|         m_cancel_callback(); | ||||
|         this->invalidate_all_steps(); | ||||
|         for (PrintObject *object : m_objects) { | ||||
|             model_object_status.emplace(object->model_object()->id(), ModelObjectStatus::Deleted); | ||||
|  | @ -746,6 +750,8 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|         } else if (model_object_list_extended(m_model, model)) { | ||||
|             // Add new objects. Their volumes and configs will be synchronized later.
 | ||||
|             this->invalidate_step(psGCodeExport); | ||||
|             for (const ModelObject *model_object : m_model.objects) | ||||
|                 model_object_status.emplace(model_object->id(), ModelObjectStatus::Old); | ||||
|             for (size_t i = m_model.objects.size(); i < model.objects.size(); ++ i) { | ||||
|                 model_object_status.emplace(model.objects[i]->id(), ModelObjectStatus::New); | ||||
|                 m_model.objects.emplace_back(model.objects[i]->clone(&m_model)); | ||||
|  | @ -770,7 +776,7 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|                 } else { | ||||
|                     // Existing ModelObject re-added (possibly moved in the list).
 | ||||
|                     m_model.objects.emplace_back(*it); | ||||
|                     model_object_status.emplace(mobj->id(), ModelObjectStatus::Old); | ||||
|                     model_object_status.emplace(mobj->id(), ModelObjectStatus::Moved); | ||||
|                 } | ||||
|             } | ||||
|             bool deleted_any = false; | ||||
|  | @ -835,7 +841,7 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|             // PrintObject instances will be added in the next loop.
 | ||||
|             continue; | ||||
|         // Update the ModelObject instance, possibly invalidate the linked PrintObjects.
 | ||||
|         assert(it_status->status == ModelObjectStatus::Moved); | ||||
|         assert(it_status->status == ModelObjectStatus::Old || it_status->status == ModelObjectStatus::Moved); | ||||
|         const ModelObject &model_object_new = *model.objects[idx_model_object]; | ||||
|         // Check whether a model part volume was added or removed, their transformations or order changed.
 | ||||
|         bool model_parts_differ         = model_volume_list_changed(model_object, model_object_new, ModelVolume::MODEL_PART); | ||||
|  | @ -864,87 +870,187 @@ bool Print::apply(const Model &model, const DynamicPrintConfig &config) | |||
|         } | ||||
|         if (! model_parts_differ && ! modifiers_differ) { | ||||
|             // Synchronize the remaining data of ModelVolumes (name, config, m_type, m_material_id)
 | ||||
|             // Synchronize Object's config.
 | ||||
|             t_config_option_keys &this_object_config_diff = const_cast<ModelObjectStatus&>(*it_status).object_config_diff; | ||||
|             this_object_config_diff = model_object.config.diff(model_object_new.config); | ||||
|             if (! this_object_config_diff.empty()) | ||||
|                 model_object.config.apply_only(model_object_new.config, this_object_config_diff, true); | ||||
|             if (! this_object_config_diff.empty() || ! this_object_config_diff.empty()) { | ||||
|                 PrintObjectConfig new_config = m_default_object_config; | ||||
|                 normalize_and_apply_config(new_config, model_object.config); | ||||
|                 auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id())); | ||||
|                 for (auto it = range.first; it != range.second; ++ it) { | ||||
|                     t_config_option_keys diff = it->print_object->config().diff(new_config); | ||||
|                     invalidated |= it->print_object->invalidate_state_by_config_options(diff); | ||||
|                     it->print_object->config_apply_only(new_config, diff, true); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 4) Generate PrintObjects from ModelObjects and their instances.
 | ||||
|     std::vector<PrintObject*> print_objects_new; | ||||
|     print_objects_new.reserve(std::max(m_objects.size(), m_model.objects.size())); | ||||
|     // Walk over all new model objects and check, whether there are matching PrintObjects.
 | ||||
|     for (ModelObject *model_object : m_model.objects) { | ||||
|         auto range = print_object_status.equal_range(PrintObjectStatus(model_object->id())); | ||||
|         std::vector<const PrintObjectStatus*> old; | ||||
|         if (range.first != range.second) { | ||||
|             old.reserve(print_object_status.count(PrintObjectStatus(model_object->id()))); | ||||
|             for (auto it = range.first; it != range.second; ++ it) | ||||
|                 if (it->status != PrintObjectStatus::Deleted) | ||||
|                     old.emplace_back(&(*it)); | ||||
|     { | ||||
|         std::vector<PrintObject*> print_objects_new; | ||||
|         print_objects_new.reserve(std::max(m_objects.size(), m_model.objects.size())); | ||||
|         // Walk over all new model objects and check, whether there are matching PrintObjects.
 | ||||
|         for (ModelObject *model_object : m_model.objects) { | ||||
|             auto range = print_object_status.equal_range(PrintObjectStatus(model_object->id())); | ||||
|             std::vector<const PrintObjectStatus*> old; | ||||
|             if (range.first != range.second) { | ||||
|                 old.reserve(print_object_status.count(PrintObjectStatus(model_object->id()))); | ||||
|                 for (auto it = range.first; it != range.second; ++ it) | ||||
|                     if (it->status != PrintObjectStatus::Deleted) | ||||
|                         old.emplace_back(&(*it)); | ||||
|             } | ||||
|             // Generate a list of trafos and XY offsets for instances of a ModelObject
 | ||||
|             PrintObjectConfig config = m_default_object_config; | ||||
|             normalize_and_apply_config(config, model_object->config); | ||||
|             std::vector<PrintInstances> new_print_instances = print_objects_from_model_object(*model_object); | ||||
|             if (old.empty()) { | ||||
|                 // Simple case, just generate new instances.
 | ||||
|                 for (const PrintInstances &print_instances : new_print_instances) { | ||||
|                     PrintObject *print_object = new PrintObject(this, model_object, model_object->raw_bounding_box()); | ||||
|                     print_object->set_copies(print_instances.copies); | ||||
|                     print_object->config_apply(config); | ||||
|                     print_objects_new.emplace_back(print_object); | ||||
|                     print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New)); | ||||
|                 } | ||||
|                 continue; | ||||
|             } | ||||
|             // Complex case, try to merge the two lists.
 | ||||
|             // Sort the old lexicographically by their trafos.
 | ||||
|             std::sort(old.begin(), old.end(), [](const PrintObjectStatus *lhs, const PrintObjectStatus *rhs){ return transform3d_lower(lhs->trafo, rhs->trafo); }); | ||||
|             // Merge the old / new lists.
 | ||||
|             auto it_old = old.begin(); | ||||
|             for (const PrintInstances &new_instances : new_print_instances) { | ||||
|                 for (; transform3d_lower((*it_old)->trafo, new_instances.trafo); ++ it_old); | ||||
|                 if (! transform3d_equal((*it_old)->trafo, new_instances.trafo)) { | ||||
|                     // This is a new instance (or a set of instances with the same trafo). Just add it.
 | ||||
|                     PrintObject *print_object = new PrintObject(this, model_object, model_object->raw_bounding_box()); | ||||
|                     print_object->set_copies(new_instances.copies); | ||||
|                     print_object->config_apply(config); | ||||
|                     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); | ||||
|                     (*it_old)->print_object->set_copies(new_instances.copies); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         // Generate a list of trafos and XY offsets for instances of a ModelObject
 | ||||
|         std::vector<PrintInstances> new_print_instances = print_objects_from_model_object(*model_object); | ||||
|         if (old.empty()) { | ||||
|             // Simple case, just generate new instances.
 | ||||
|             for (const PrintInstances &print_instances : new_print_instances) { | ||||
|                 PrintObject *print_object = new PrintObject(this, model_object, model_object->raw_bounding_box()); | ||||
|                 print_objects_new.emplace_back(print_object); | ||||
|                 print_object_status.emplace(PrintObjectStatus(print_object, PrintObjectStatus::New)); | ||||
|         if (m_objects != print_objects_new) { | ||||
|             m_cancel_callback(); | ||||
|             m_objects = print_objects_new; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 5) Synchronize configs of ModelVolumes, synchronize AMF / 3MF materials (and their configs), refresh PrintRegions.
 | ||||
|     // Update reference counts of regions from the remaining PrintObjects and their volumes.
 | ||||
|     // Regions with zero references could and should be reused.
 | ||||
|     for (PrintRegion *region : m_regions) | ||||
|         region->m_refcnt = 0; | ||||
|     for (PrintObject *print_object : m_objects) { | ||||
|         int idx_region = 0; | ||||
|         for (const auto &volumes : print_object->region_volumes) { | ||||
|             if (! volumes.empty()) | ||||
|                 ++ m_regions[idx_region]; | ||||
|             ++ idx_region; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // All regions now have distinct settings.
 | ||||
|     // Check whether applying the new region config defaults we'd get different regions.
 | ||||
|     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 *print_object : m_objects) { | ||||
|             if (region_id < print_object->region_volumes.size()) { | ||||
|                 for (int volume_id : print_object->region_volumes[region_id]) { | ||||
|                     const ModelVolume &volume = *print_object->model_object()->volumes[volume_id]; | ||||
|                     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(region_config_from_model_volume(m_default_region_config, volume))) | ||||
|                             // Regions were split. Reset this print_object.
 | ||||
|                             goto print_object_end; | ||||
|                     } else { | ||||
|                         this_region_config = region_config_from_model_volume(m_default_region_config, volume); | ||||
|                         for (size_t i = 0; i < region_id; ++ i) | ||||
|                             if (m_regions[i]->config().equals(this_region_config)) | ||||
|                                 // Regions were merged. Reset this print_object.
 | ||||
|                                 goto print_object_end; | ||||
|                         this_region_config_set = true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             continue; | ||||
|         print_object_end: | ||||
|             print_object->invalidate_all_steps(); | ||||
|             // Decrease the references to regions from this volume.
 | ||||
|             int ireg = 0; | ||||
|             for (const std::vector<int> &volumes : print_object->region_volumes) { | ||||
|                 if (! volumes.empty()) | ||||
|                     -- m_regions[ireg]; | ||||
|                 ++ ireg; | ||||
|             } | ||||
|             print_object->region_volumes.clear(); | ||||
|         } | ||||
|         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 *print_object : m_objects) | ||||
|                     if (region_id < print_object->region_volumes.size() && ! print_object->region_volumes[region_id].empty()) | ||||
|                         invalidated |= print_object->invalidate_state_by_config_options(diff); | ||||
|             } | ||||
|         } | ||||
|         // Complex case, try to merge the two lists.
 | ||||
|         // Sort the old lexicographically by their trafos.
 | ||||
|         std::sort(old.begin(), old.end(), [](const PrintObjectStatus *lhs, const PrintObjectStatus *rhs){ return transform3d_lower(lhs->trafo, rhs->trafo); }); | ||||
|         // Merge the old / new lists.
 | ||||
|          | ||||
|     } | ||||
|     if (m_objects != print_objects_new) { | ||||
|         m_cancel_callback(); | ||||
|         m_objects = print_objects_new; | ||||
|     } | ||||
| 
 | ||||
|     // Synchronize materials.
 | ||||
| 
 | ||||
| #if 0 | ||||
|     { | ||||
|         m_model = model; | ||||
|         for (const ModelObject *model_object : m_model.objects) { | ||||
|             PrintObject *object = new PrintObject(this, model_object, model_object->raw_bounding_box()); | ||||
|             m_objects.emplace_back(object); | ||||
|             size_t volume_id = 0; | ||||
|             for (const ModelVolume *volume : model_object->volumes) { | ||||
|     // Possibly add new regions for the newly added or resetted PrintObjects.
 | ||||
|     for (size_t idx_print_object = 0; idx_print_object < m_objects.size(); ++ idx_print_object) { | ||||
|         PrintObject        &print_object0 = *m_objects[idx_print_object]; | ||||
|         const ModelObject  &model_object  = *print_object0.model_object(); | ||||
|         std::vector<int>    map_volume_to_region(model_object.volumes.size(), -1); | ||||
|         for (size_t i = idx_print_object; i < m_objects.size() && m_objects[i]->model_object() == &model_object; ++ i) { | ||||
|             PrintObject &print_object = *m_objects[i]; | ||||
|             unsigned 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 = this->_region_config_from_model_volume(*volume); | ||||
|                 // Find an existing print region with the same config.
 | ||||
|                 size_t region_id = size_t(-1); | ||||
|                 for (size_t i = 0; i < m_regions.size(); ++ i) | ||||
|                     if (config.equals(m_regions[i]->config())) { | ||||
|                         region_id = i; | ||||
|                         break; | ||||
|                 int region_id = -1; | ||||
|                 if (&print_object == &print_object0) { | ||||
|                     // Get the config applied to this volume.
 | ||||
|                     PrintRegionConfig config = region_config_from_model_volume(m_default_region_config, *volume); | ||||
|                     // Find an existing print region with the same config.
 | ||||
|                     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 == size_t(-1)) { | ||||
|                         for (region_id = 0; region_id < m_regions.size(); ++ region_id) | ||||
|                             if (m_regions[region_id]->m_refcnt == 0) { | ||||
|                                 // An empty slot was found.
 | ||||
|                                 m_regions[region_id]->set_config(std::move(config)); | ||||
|                                 break; | ||||
|                             } | ||||
|                         if (region_id == m_regions.size()) | ||||
|                             this->add_region(config); | ||||
|                     } | ||||
|                 // If no region exists with the same config, create a new one.
 | ||||
|                 if (region_id == size_t(-1)) { | ||||
|                     region_id = m_regions.size(); | ||||
|                     this->add_region(config); | ||||
|                 } | ||||
|                     map_volume_to_region[volume_id] = region_id; | ||||
|                 } else | ||||
|                     region_id = map_volume_to_region[volume_id]; | ||||
|                 // Assign volume to a region.
 | ||||
|                 object->add_region_volume(region_id, volume_id); | ||||
|                 if (volume_id >= print_object.region_volumes.size()) | ||||
|                     print_object.add_region_volume(region_id, volume_id); | ||||
|                 ++ 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); | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         // Synchronize m_model.objects with model.objects
 | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     this->update_object_placeholders(); | ||||
| } | ||||
|  | @ -1284,16 +1390,6 @@ Flow Print::skirt_flow() const | |||
|     ); | ||||
| } | ||||
| 
 | ||||
| PrintRegionConfig Print::_region_config_from_model_volume(const ModelVolume &volume) | ||||
| { | ||||
|     PrintRegionConfig config = this->default_region_config(); | ||||
|     normalize_and_apply_config(config, volume.get_object()->config); | ||||
|     normalize_and_apply_config(config, volume.config); | ||||
|     if (! volume.material_id().empty()) | ||||
|         normalize_and_apply_config(config, volume.material()->config); | ||||
|     return config; | ||||
| } | ||||
| 
 | ||||
| bool Print::has_support_material() const | ||||
| { | ||||
|     for (const PrintObject *object : m_objects) | ||||
|  |  | |||
|  | @ -139,19 +139,25 @@ public: | |||
|     // Average diameter of nozzles participating on extruding this region.
 | ||||
|     coordf_t                    nozzle_dmr_avg(const PrintConfig &print_config) const; | ||||
|     // Average diameter of nozzles participating on extruding this region.
 | ||||
|     coordf_t bridging_height_avg(const PrintConfig &print_config) const; | ||||
|     coordf_t                    bridging_height_avg(const PrintConfig &print_config) const; | ||||
| 
 | ||||
| // Methods modifying the PrintRegion's state:
 | ||||
| public: | ||||
|     Print*                      print() { return m_print; } | ||||
|     void                        config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) { this->m_config.apply_only(other, keys, ignore_nonexistent); } | ||||
|     void                        set_config(const PrintRegionConfig &config) { m_config = config; } | ||||
|     void                        set_config(PrintRegionConfig &&config) { m_config = std::move(config); } | ||||
|     void                        config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false)  | ||||
|                                         { this->m_config.apply_only(other, keys, ignore_nonexistent); } | ||||
| 
 | ||||
| protected: | ||||
|     size_t             m_refcnt; | ||||
| 
 | ||||
| private: | ||||
|     Print             *m_print; | ||||
|     PrintRegionConfig  m_config; | ||||
|      | ||||
|     PrintRegion(Print* print) : m_print(print) {} | ||||
|     PrintRegion(Print* print, const PrintRegionConfig &config) : m_print(print), m_config(config) {} | ||||
|     PrintRegion(Print* print) : m_refcnt(0), m_print(print) {} | ||||
|     PrintRegion(Print* print, const PrintRegionConfig &config) : m_refcnt(0), m_print(print), m_config(config) {} | ||||
|     ~PrintRegion() {} | ||||
| }; | ||||
| 
 | ||||
|  | @ -196,12 +202,13 @@ public: | |||
|     const SupportLayerPtrs& support_layers() const  { return m_support_layers; } | ||||
|     const Transform3d&      trafo() const           { return m_trafo; } | ||||
| 
 | ||||
|     const Points& copies() const { return m_copies; } | ||||
|     bool add_copy(const Vec2d &point); | ||||
|     bool delete_last_copy(); | ||||
|     bool delete_all_copies() { return this->set_copies(Points()); } | ||||
|     bool set_copies(const Points &points); | ||||
|     bool reload_model_instances(); | ||||
|     const Points&           copies() const { return m_copies; } | ||||
|     bool                    add_copy(const Vec2d &point); | ||||
|     bool                    delete_last_copy(); | ||||
|     bool                    delete_all_copies() { return this->set_copies(Points()); } | ||||
|     bool                    set_copies(const Points &points); | ||||
|     bool                    reload_model_instances(); | ||||
| 
 | ||||
|     // since the object is aligned to origin, bounding box coincides with size
 | ||||
|     BoundingBox bounding_box() const { return BoundingBox(Point(0,0), to_2d(this->size)); } | ||||
| 
 | ||||
|  | @ -486,7 +493,6 @@ private: | |||
|     void                update_object_placeholders(); | ||||
| 
 | ||||
|     bool                invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys); | ||||
|     PrintRegionConfig   _region_config_from_model_volume(const ModelVolume &volume); | ||||
| 
 | ||||
|     // If the background processing stop was requested, throw CanceledException.
 | ||||
|     // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv