mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-07 18:17:44 +00:00
Six issues found by reviewing the previous commit against belt-printer, two of them release-blocking. Data race (high). Print::process() runs generate_support_material() for all objects in a tbb::parallel_for, and make_belt_brim() runs at its tail, but belt_brim_obstacles() read every OTHER object's support_layers() - which a concurrent task may be inside clear_support_layers() deleting. That is a use-after-free, and even when it survives, the obstacle set depends on which object finishes first. Only this object's own supports are consulted now; they are complete at that point. Foreign objects still contribute their slices, which are finished and immutable before the support phase. Apron bands dropped (high), two separate causes. An apron band prints below its own object's first layer, but another object can already be printing at that print_z, in which case process_layer() takes the ordinary path and never emitted the band - the emission is now shared by both paths. Separately, a band whose print_z matched a support layer of the SAME object was overwritten in the print-wide merge, which keeps one record per object per z and could not detect the collision because LayerToPrint::layer() is null for a band. The per-object pairing loop is now a three-way merge over object, support and apron streams, so each object contributes at most one record per z. Multi-instance was far too strict (medium). It refused belt brim for every multi-instance object, killing plain brim width and inner brim too, and only warned when a leading length was set. Only movement ALONG the belt changes an instance's belt-floor Z, so copies side by side ACROSS the belt share one set of bands perfectly well; belt_brim_instances_compatible() now tests just that, and the warning fires whenever the brim is actually suppressed. Apron layer bookkeeping (medium). Apron layers count toward m_layer_count and advance m_layer_index, but emitted no Z/height tags, left m_last_layer_z, m_max_layer_z and m_last_height stale - so the first object layer computed its height against a pre-apron Z - and skipped before_layer_change_gcode and layer_change_gcode entirely. All of that now matches the ordinary path. Obstacle cost (low). belt_brim_obstacles() ran a full-plate union per band. A bounding-box pre-filter drops non-overlapping objects before materialising any polygon, and the union is skipped for trivial inputs. Deliberately unchanged: every apron band still reports cooling layer_id 0. CoolingBuffer uses it for the initial_layer_fan_speed override and the close_fan_the_first_x_layers gate, and every band lies on the belt plane itself, so it is all first-layer material by the only definition that means anything on a belt. Numbering the bands would ramp the fan up while still printing on the belt. Now documented at the assignment rather than left implicit.