Merge upstream/main into cad-mainline (530 commits)

Catches the fork up from 449a4cf9fc (2026-06-28) to d6cb667b89 (2026-07-24).
Upstream touched 2326 files; 17 of them overlap the 164 this branch touches.

16 of the 17 auto-merged, including all three CMakeLists.txt, the build_all.yml
CI workflow, and every GUI file. The CAD core never conflicts: CadDocument,
SketchEngine, SketchSolver, McpControl and test_caddocument are files this fork
adds, so upstream does not touch them.

The one conflict, tests/libslic3r/test_3mf.cpp, was purely additive in all three
hunks and is resolved as a union: our test pinning that store_bbs_3mf embeds the
CAD recipe as Metadata/SnapOrca_cad.bin, upstream's multi-nozzle plate-metadata
round-trip tests, and both sets of includes. All three were verified present
after resolution rather than assumed.

NOT BUILD-VERIFIED, for a reason that predates this merge and is not caused by
it: this fork cannot be configured on nativedev at all. Its CMakeLists has
required Eigen3 5.0.1 since before the merge (line 592 pre-merge), while the
only deps image on the machine is snaporca-deps, built for snaporca's
find_package(Eigen3 3.3). CMake fails at configure, so nothing compiles.

That means this fork's Catch2 suite has never run. Every "suite green" figure
recorded for M1-M8 was snaporca's suite; the ports were verified by patch-apply
plus the CAD sources being byte-identical to snaporca's. Building an orca_cad
deps image with Eigen 5.0.1 is what would finally close that gap.

Pre-merge state is preserved at branch cad-mainline-pre-upstream-2026-07-25
(30d54f0074).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tommaso Bianchi
2026-07-25 12:28:33 +02:00
co-authored by Claude Opus 5
2326 changed files with 2562372 additions and 1267981 deletions
+21 -18
View File
@@ -190,8 +190,8 @@ Model Model::read_from_step(const std::string&
ImportStepProgressFn stepFn,
StepIsUtf8Fn stepIsUtf8Fn,
std::function<int(Slic3r::Step&, double&, double&, bool&)> step_mesh_fn,
double linear_defletion,
double angle_defletion,
double linear_deflection,
double angle_deflection,
bool is_split_compound)
{
Model model;
@@ -204,13 +204,13 @@ Model Model::read_from_step(const std::string&
goto _finished;
}
if (step_mesh_fn) {
if (step_mesh_fn(step_file, linear_defletion, angle_defletion, is_split_compound) == -1) {
if (step_mesh_fn(step_file, linear_deflection, angle_deflection, is_split_compound) == -1) {
status = Step::Step_Status::CANCEL;
goto _finished;
}
}
status = step_file.mesh(&model, is_cb_cancel, is_split_compound, linear_defletion, angle_defletion);
status = step_file.mesh(&model, is_cb_cancel, is_split_compound, linear_deflection, angle_deflection);
_finished:
@@ -2975,31 +2975,31 @@ void Model::setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConf
//Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config();
printSpeedMap.maxSpeed = 0;
if (config.has("inner_wall_speed")) {
printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed");
printSpeedMap.perimeterSpeed = config.opt_float_nullable("inner_wall_speed", 0);
if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed)
printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed;
}
if (config.has("outer_wall_speed")) {
printSpeedMap.externalPerimeterSpeed = config.opt_float("outer_wall_speed");
printSpeedMap.externalPerimeterSpeed = config.opt_float_nullable("outer_wall_speed", 0);
printSpeedMap.maxSpeed = std::max(printSpeedMap.maxSpeed, printSpeedMap.externalPerimeterSpeed);
}
if (config.has("sparse_infill_speed")) {
printSpeedMap.infillSpeed = config.opt_float("sparse_infill_speed");
printSpeedMap.infillSpeed = config.opt_float_nullable("sparse_infill_speed", 0);
if (printSpeedMap.infillSpeed > printSpeedMap.maxSpeed)
printSpeedMap.maxSpeed = printSpeedMap.infillSpeed;
}
if (config.has("internal_solid_infill_speed")) {
printSpeedMap.solidInfillSpeed = config.opt_float("internal_solid_infill_speed");
printSpeedMap.solidInfillSpeed = config.opt_float_nullable("internal_solid_infill_speed", 0);
if (printSpeedMap.solidInfillSpeed > printSpeedMap.maxSpeed)
printSpeedMap.maxSpeed = printSpeedMap.solidInfillSpeed;
}
if (config.has("top_surface_speed")) {
printSpeedMap.topSolidInfillSpeed = config.opt_float("top_surface_speed");
printSpeedMap.topSolidInfillSpeed = config.opt_float_nullable("top_surface_speed", 0);
if (printSpeedMap.topSolidInfillSpeed > printSpeedMap.maxSpeed)
printSpeedMap.maxSpeed = printSpeedMap.topSolidInfillSpeed;
}
if (config.has("support_speed")) {
printSpeedMap.supportSpeed = config.opt_float("support_speed");
printSpeedMap.supportSpeed = config.opt_float_nullable("support_speed", 0);
if (printSpeedMap.supportSpeed > printSpeedMap.maxSpeed)
printSpeedMap.maxSpeed = printSpeedMap.supportSpeed;
@@ -3229,25 +3229,28 @@ double Model::findMaxSpeed(const ModelObject* object) {
double topSolidInfillSpeedObj = Model::printSpeedMap.topSolidInfillSpeed;
double supportSpeedObj = Model::printSpeedMap.supportSpeed;
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
double smallSupportPerimeterSpeedObj = Model::printSpeedMap.smallSupportPerimeterSpeed;
for (std::string objectKey : objectKeys) {
if (objectKey == "inner_wall_speed"){
perimeterSpeedObj = object->config.opt_float(objectKey);
perimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
externalPerimeterSpeedObj = Model::printSpeedMap.externalPerimeterSpeed / Model::printSpeedMap.perimeterSpeed * perimeterSpeedObj;
}
if (objectKey == "sparse_infill_speed")
infillSpeedObj = object->config.opt_float(objectKey);
infillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "internal_solid_infill_speed")
solidInfillSpeedObj = object->config.opt_float(objectKey);
solidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "top_surface_speed")
topSolidInfillSpeedObj = object->config.opt_float(objectKey);
topSolidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "support_speed")
supportSpeedObj = object->config.opt_float(objectKey);
supportSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "outer_wall_speed")
externalPerimeterSpeedObj = object->config.opt_float(objectKey);
externalPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "small_perimeter_speed")
smallPerimeterSpeedObj = object->config.opt_float(objectKey);
smallPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
if (objectKey == "small_support_perimeter_speed")
smallSupportPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
}
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, objMaxSpeed)))))));
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, std::max(smallSupportPerimeterSpeedObj, objMaxSpeed))))))));
if (objMaxSpeed <= 0) objMaxSpeed = 250.;
return objMaxSpeed;
}