Compare commits

..
Author SHA1 Message Date
ExPikaPaka 991d421756 Stop reading a missing AMF metadata type as a string
A <metadata> element without a type attribute makes get_attribute() return
nullptr, which is then assigned to a std::string and read as a C string.

Check it the way the sibling metadata handler already does and stop the parse.
2026-10-01 08:50:05 +02:00
8 changed files with 57 additions and 39 deletions
+7 -2
View File
@@ -311,8 +311,13 @@ void AMFParserContext::startElement(const char *name, const char **atts)
case 2:
if (strcmp(name, "metadata") == 0) {
if (m_path[1] == NODE_TYPE_MATERIAL || m_path[1] == NODE_TYPE_OBJECT) {
m_value[0] = get_attribute(atts, "type");
node_type_new = NODE_TYPE_METADATA;
const char *type = get_attribute(atts, "type");
if (type == nullptr)
this->stop();
else {
m_value[0] = type;
node_type_new = NODE_TYPE_METADATA;
}
}
}/* else if (strcmp(name, "layer_config_ranges") == 0 && m_path[1] == NODE_TYPE_OBJECT)
node_type_new = NODE_TYPE_LAYER_CONFIG;*/
+3 -3
View File
@@ -360,7 +360,7 @@ void Layer::simplify_support_entity_collection(ExtrusionEntityCollection* entity
//BBS: method to simplify support path
void Layer::simplify_support_path(ExtrusionPath * path)
{
const PrintConfig &print_config = this->object()->print()->config();
const auto print_config = this->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
@@ -375,7 +375,7 @@ void Layer::simplify_support_path(ExtrusionPath * path)
//BBS: method to simplify support path
void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
{
const PrintConfig &print_config = this->object()->print()->config();
const auto print_config = this->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
@@ -392,7 +392,7 @@ void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
//BBS: method to simplify support path
void Layer::simplify_support_loop(ExtrusionLoop* loop)
{
const PrintConfig &print_config = this->object()->print()->config();
const auto print_config = this->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
+3 -3
View File
@@ -1074,7 +1074,7 @@ void LayerRegion::simplify_entity_collection(ExtrusionEntityCollection* entity_c
void LayerRegion::simplify_path(ExtrusionPath* path)
{
const PrintConfig &print_config = this->layer()->object()->print()->config();
const auto print_config = this->layer()->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
@@ -1092,7 +1092,7 @@ void LayerRegion::simplify_path(ExtrusionPath* path)
void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
{
const PrintConfig &print_config = this->layer()->object()->print()->config();
const auto print_config = this->layer()->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
@@ -1112,7 +1112,7 @@ void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
void LayerRegion::simplify_loop(ExtrusionLoop* loop)
{
const PrintConfig &print_config = this->layer()->object()->print()->config();
const auto print_config = this->layer()->object()->print()->config();
const bool spiral_mode = print_config.spiral_mode;
const bool enable_arc_fitting = print_config.enable_arc_fitting;
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
+11 -13
View File
@@ -2604,11 +2604,6 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
void PrintObject::set_shared_object(PrintObject *object)
{
// Orca: from now on m_layers / m_support_layers only alias the shared object's layers, so release the
// ones this object still owns (it may have sliced itself before it became shareable again).
// Both are no-ops once m_shared_object is set, so this cannot free layers owned by another object.
clear_support_layers();
clear_layers();
m_shared_object = object;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, found shared object from %2%")%this%m_shared_object;
}
@@ -4334,9 +4329,9 @@ bool Print::is_dynamic_group_reorder() const
return true;
}
int Print::get_filament_config_indx(int filament_id, int layer_id)
int Print::get_filament_config_indx(int filament_id, int layer_id, bool use_cache)
{
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, m_filament_index_map);
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, use_cache ? &m_filament_index_map : nullptr);
}
void Print::update_filament_self_index_cache()
@@ -4379,7 +4374,7 @@ int Print::get_nozzle_config_index(int filament_id, int layer_id)
return get_config_index(filament_id, layer_id, m_default_region_config.print_extruder_variant.values, m_default_region_config.print_extruder_id.values, m_nozzle_index_map);
}
int Print::get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, FilamentIndexMap &index_map)
int Print::get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, FilamentIndexMap *index_map)
{
auto group_result = get_layered_nozzle_group_result();
// Orca: defensive — when no grouping producer has published a result yet, fall back to the
@@ -4390,7 +4385,8 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
if (!nozzle_info.has_value()) {
// Orca: this fallback runs per-filament/per-layer in the g-code hot path — log once per filament
// (reset each slice) instead of flooding thousands of identical lines that bury the real error.
if (m_missing_nozzle_group_logged.insert(filament_id).second)
// Without the cache, the log set is left alone too; the cached caller reports the same filament.
if (index_map && m_missing_nozzle_group_logged.insert(filament_id).second)
BOOST_LOG_TRIVIAL(error) << __FUNCTION__
<< boost::format(", Line %1%: could not found group_nozzle_info corresponding to filament_id %2%, layer_id %3% (further occurrences for this filament suppressed)") % __LINE__ % filament_id %
layer_id;
@@ -4399,15 +4395,17 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
ExtruderType extruder_type = ExtruderType(m_config.extruder_type.get_at(nozzle_info->extruder_id));
NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type;
if (!index_map)
return get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
FilamentIndexKey key{filament_id, extruder_type, nozzle_volume_type};
auto iter = index_map.find(key);
if (iter == index_map.end()) {
auto iter = index_map->find(key);
if (iter == index_map->end()) {
int index = get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
index_map[key] = index;
(*index_map)[key] = index;
return index;
} else {
return index_map[key];
return iter->second;
}
}
-3
View File
@@ -987,9 +987,6 @@ void PrintObject::generate_support_material()
this->_generate_support_material();
m_print->throw_if_canceled();
}
// Orca: the tree support collision/avoidance caches and support nodes are only used while this step runs
// (detect_overhangs() rebuilds them from scratch), so don't keep them resident until the next slice.
this->clear_tree_support_preview_cache();
this->set_done(posSupportMaterial);
}
}
+1 -1
View File
@@ -1346,7 +1346,7 @@ void PrintObject::slice_volumes()
if (min_growth < 0.f || elfoot > 0.f) {
// Apply the negative XY compensation. (the ones that is <0)
ExPolygons trimming;
const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
if (elfoot > 0.f) {
ExPolygons expolygons_to_compensate = offset_ex(layer->merged(eps), -eps);
lslices_elfoot_uncompensated[layer_id] = expolygons_to_compensate;
+30 -12
View File
@@ -1820,15 +1820,37 @@ coordf_t TreeSupport::get_radius(const SupportNode* node)
return node->radius;
}
// Orca: these are hit up to several times per node per layer in drop_nodes(), so hand out a
// reference into the TreeSupportData cache instead of copying the ExPolygons out of it.
const ExPolygons& TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr)
ExPolygons TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr)
{
#if USE_SUPPORT_3D
if (m_model_volumes) {
bool on_build_plate = m_object_config->support_on_build_plate_only.value;
const Polygons& avoid_polys = m_model_volumes->getAvoidance(radius, obj_layer_nr, TreeSupport3D::TreeModelVolumes::AvoidanceType::FastSafe, on_build_plate, true);
ExPolygons expolys;
for (auto& poly : avoid_polys)
expolys.emplace_back(std::move(poly));
return expolys;
}
return ExPolygons();
#else
return m_ts_data->get_avoidance(radius, obj_layer_nr);
#endif
}
const ExPolygons& TreeSupport::get_collision(coordf_t radius, size_t layer_nr)
ExPolygons TreeSupport::get_collision(coordf_t radius, size_t layer_nr)
{
#if USE_SUPPORT_3D
if (m_model_volumes) {
bool on_build_plate = m_object_config->support_on_build_plate_only.value;
const Polygons& collision_polys = m_model_volumes->getCollision(radius, layer_nr, true);
ExPolygons expolys;
for (auto& poly : collision_polys)
expolys.emplace_back(std::move(poly));
return expolys;
}
#else
return m_ts_data->get_collision(radius, layer_nr);
#endif
return ExPolygons();
}
Polygons TreeSupport::get_collision_polys(coordf_t radius, size_t layer_nr)
{
@@ -2617,11 +2639,7 @@ void TreeSupport::draw_circles()
#endif // SUPPORT_TREE_DEBUG_TO_SVG
SupportLayerPtrs& ts_layers = m_object->support_layers();
// Orca: the vector owns its layers, so the dropped ones have to be deleted, not just unlinked.
// std::stable_partition (unlike std::remove_if) leaves exactly the dropped layers in the tail.
auto iter = std::stable_partition(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height >= EPSILON; });
for (auto it = iter; it != ts_layers.end(); ++it)
delete *it;
auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height < EPSILON; });
ts_layers.erase(iter, ts_layers.end());
for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) {
ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr;
@@ -2864,7 +2882,7 @@ void TreeSupport::drop_nodes()
//Insert a completely new node and let both original nodes fade.
Point next_position = (node.position + neighbours[0]) / 2; //Average position of the two nodes.
coordf_t next_radius = calc_radius(node.dist_mm_to_top+height_next);
const ExPolygons& avoid_layer = get_avoidance(next_radius, obj_layer_nr_next);
auto avoid_layer = get_avoidance(next_radius, obj_layer_nr_next);
if (group_index == 0)
{
//Avoid collisions.
@@ -3051,7 +3069,7 @@ void TreeSupport::drop_nodes()
}
#endif
coordf_t next_radius = calc_radius(node.dist_mm_to_top + height_next);
const ExPolygons& avoidance_next = get_avoidance(next_radius, obj_layer_nr_next);
auto avoidance_next = get_avoidance(next_radius, obj_layer_nr_next);
Point to_outside = projection_onto(avoidance_next, node.position);
Point direction_to_outer = to_outside - node.position;
@@ -3105,7 +3123,7 @@ void TreeSupport::drop_nodes()
if (is_outside) { next_layer_vertex = candidate_vertex; }
}
}
const ExPolygons& next_collision = get_collision(0, obj_layer_nr_next);
auto next_collision = get_collision(0, obj_layer_nr_next);
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[obj_layer_nr_next], next_layer_vertex);
// don't increase radius if next node will collide partially with the object (STUDIO-7883)
to_outside = projection_onto(next_collision, next_layer_vertex);
+2 -2
View File
@@ -511,9 +511,9 @@ private:
coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true);
coordf_t calc_radius(coordf_t mm_to_top);
coordf_t get_radius(const SupportNode* node);
const ExPolygons& get_avoidance(coordf_t radius, size_t obj_layer_nr);
ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr);
// layer's expolygon expanded by radius+m_xy_distance
const ExPolygons& get_collision(coordf_t radius, size_t layer_nr);
ExPolygons get_collision(coordf_t radius, size_t layer_nr);
// get Polygons instead of ExPolygons
Polygons get_collision_polys(coordf_t radius, size_t layer_nr);