mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-10 17:21:10 +00:00
Merge branch 'OrcaSlicer:main' into main
This commit is contained in:
+1
-10
@@ -1,13 +1,9 @@
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "4.0")
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "" FORCE)
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.13 CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# Verify that your CMake version is exactly 3.5 series or higher on windows
|
||||
if ( (MSVC OR WIN32) AND (${CMAKE_VERSION} VERSION_LESS "3.5") )
|
||||
message(FATAL_ERROR "CMake current version ${CMAKE_VERSION} is too old. Minimum required is 3.5.")
|
||||
endif()
|
||||
|
||||
# The following line used to be in tests/CMakeLists.txt
|
||||
# Having it there causes rebuilds of all targets on any CMakeLists.txt change under tests/
|
||||
@@ -377,11 +373,6 @@ endif ()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1")
|
||||
# Workaround for an old CMake, which does not understand CMAKE_CXX_STANDARD.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
# Boost on Raspberry-Pi does not link to pthreads.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
@@ -4,7 +4,7 @@ msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-20 23:26+0800\n"
|
||||
"PO-Revision-Date: 2026-03-08 21:15-0300\n"
|
||||
"PO-Revision-Date: 2026-03-22 17:15-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -5025,7 +5025,7 @@ msgid "Actual Speed: "
|
||||
msgstr "Velocidade Real: "
|
||||
|
||||
msgid "PA: "
|
||||
msgstr "PA: "
|
||||
msgstr "AP: "
|
||||
|
||||
msgid "Statistics of All Plates"
|
||||
msgstr "Estatísticas de Todas as Placas"
|
||||
@@ -5436,7 +5436,7 @@ msgid "Return"
|
||||
msgstr "Retornar"
|
||||
|
||||
msgid "Canvas Toolbar"
|
||||
msgstr "Barra de ferramentas da tela"
|
||||
msgstr "Barra de Ferramentas de Tela"
|
||||
|
||||
msgid "Fit camera to scene or selected object."
|
||||
msgstr "Ajustar câmera à cena ou objeto selecionado."
|
||||
@@ -6061,10 +6061,10 @@ msgid "Retraction test"
|
||||
msgstr "Teste de retração"
|
||||
|
||||
msgid "Cornering"
|
||||
msgstr "Curvas"
|
||||
msgstr "Quinas"
|
||||
|
||||
msgid "Cornering calibration"
|
||||
msgstr "Calibração de curvas"
|
||||
msgstr "Calibração de quinas"
|
||||
|
||||
msgid "Input Shaping Frequency"
|
||||
msgstr "Frequência da Modelagem de Entrada"
|
||||
@@ -7226,13 +7226,13 @@ msgid "Enable AI monitoring of printing"
|
||||
msgstr "Ativar monitoramento de IA da impressão"
|
||||
|
||||
msgid "Pausing Sensitivity:"
|
||||
msgstr "Sensibilidade de pausa:"
|
||||
msgstr "Sensibilidade de Pausa:"
|
||||
|
||||
msgid "Spaghetti Detection"
|
||||
msgstr "Detecção de Emaranhado"
|
||||
|
||||
msgid "Detect spaghetti failures (scattered lose filament)."
|
||||
msgstr "Detectar falhas de espaguete (filamento solto espalhado)."
|
||||
msgstr "Detectar falhas de emaranhado (filamento solto espalhado)."
|
||||
|
||||
msgid "Purge Chute Pile-Up Detection"
|
||||
msgstr "Detecção de Acúmulo na Calha de Purga"
|
||||
@@ -9826,8 +9826,8 @@ msgid ""
|
||||
"Enabling both precise Z height and the prime tower may cause slicing errors. "
|
||||
"Do you still want to enable?"
|
||||
msgstr ""
|
||||
"Habilitar tanto a altura Z precisa quanto a torre de preparação pode causar "
|
||||
"erros de fatiamento. Deseja continuar habilitando?"
|
||||
"Habilitar a altura Z precisa e a torre de preparação juntas pode causar "
|
||||
"erros de fatiamento. Deseja habilitar mesmo assim?"
|
||||
|
||||
msgid ""
|
||||
"A prime tower is required for clumping detection. There may be flaws on the "
|
||||
@@ -9841,8 +9841,8 @@ msgid ""
|
||||
"Enabling both precise Z height and the prime tower may cause slicing errors. "
|
||||
"Do you still want to enable precise Z height?"
|
||||
msgstr ""
|
||||
"Habilitar tanto a altura Z precisa quanto a torre de preparação pode causar "
|
||||
"erros de fatiamento. Deseja continuar habilitando a altura Z precisa?"
|
||||
"Habilitar a altura Z precisa e a torre de preparação juntas pode causar "
|
||||
"erros de fatiamento. Deseja habilitar a altura Z precisa mesmo assim?"
|
||||
|
||||
msgid ""
|
||||
"A prime tower is required for smooth timelapse. There may be flaws on the "
|
||||
@@ -11154,7 +11154,7 @@ msgid "Configuration package changed"
|
||||
msgstr "Pacote de configuração alterado"
|
||||
|
||||
msgid "Toolbar"
|
||||
msgstr "Barra de ferramentas"
|
||||
msgstr "Barra de Ferramentas"
|
||||
|
||||
msgid "Objects list"
|
||||
msgstr "Lista de objetos"
|
||||
@@ -11885,7 +11885,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"Enabling both precise Z height and the prime tower may cause slicing errors."
|
||||
msgstr ""
|
||||
"Habilitar tanto a altura Z precisa quanto a torre de preparação pode causar "
|
||||
"Habilitar a altura Z precisa e a torre de preparação juntas pode causar "
|
||||
"erros de fatiamento."
|
||||
|
||||
msgid ""
|
||||
@@ -13947,7 +13947,7 @@ msgstr ""
|
||||
"adaptativa deve ser expandida nas direções XY."
|
||||
|
||||
msgid "Grab length"
|
||||
msgstr "Comprimento de agarre"
|
||||
msgstr "Comprimento de pega"
|
||||
|
||||
msgid "Extruder Color"
|
||||
msgstr "Cor da Extrusora"
|
||||
@@ -14631,7 +14631,7 @@ msgstr ""
|
||||
"suporte."
|
||||
|
||||
msgid "Filament ramming length"
|
||||
msgstr "Comprimento de compactação do filamento"
|
||||
msgstr "Comprimento de moldeamento do filamento"
|
||||
|
||||
msgid ""
|
||||
"When changing the extruder, it is recommended to extrude a certain length of "
|
||||
@@ -17427,7 +17427,7 @@ msgid "Purge remaining filament into prime tower."
|
||||
msgstr "Purgar o filamento restante na torre de preparo."
|
||||
|
||||
msgid "Enable filament ramming"
|
||||
msgstr "Habilitar compactação de filamento"
|
||||
msgstr "Habilitar moldeamento de filamento"
|
||||
|
||||
msgid "No sparse layers (beta)"
|
||||
msgstr "Sem camadas esparsas (beta)"
|
||||
@@ -19904,13 +19904,13 @@ msgid "Record Factor"
|
||||
msgstr "Registrar Fator"
|
||||
|
||||
msgid "We found the best flow ratio for you"
|
||||
msgstr "Encontramos o melhor fluxo para você"
|
||||
msgstr "Encontramos a melhor taxa de fluxo para você"
|
||||
|
||||
msgid "Flow Ratio"
|
||||
msgstr "Fluxo"
|
||||
msgstr "Taxa de Fluxo"
|
||||
|
||||
msgid "Please input a valid value (0.0 < flow ratio < 2.0)"
|
||||
msgstr "Por favor insira um valor válido (0.0 < fluxo < 2.0)"
|
||||
msgstr "Por favor insira um valor válido (0.0 < taxa de fluxo < 2.0)"
|
||||
|
||||
msgid "Please enter the name of the preset you want to save."
|
||||
msgstr "Por favor insira o nome da predefinição que você deseja salvar."
|
||||
@@ -19932,7 +19932,7 @@ msgstr "Pular Calibração2"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "flow ratio : %s "
|
||||
msgstr "fluxo: %s "
|
||||
msgstr "taxa de fluxo: %s "
|
||||
|
||||
msgid "Please choose a block with smoothest top surface."
|
||||
msgstr "Por favor escolha um bloco com a superfície superior mais lisa."
|
||||
@@ -19948,7 +19948,7 @@ msgid "Complete Calibration"
|
||||
msgstr "Calibração Completa"
|
||||
|
||||
msgid "Fine Calibration based on flow ratio"
|
||||
msgstr "Calibração Fina baseada no fluxo"
|
||||
msgstr "Calibração Fina baseada na taxa de fluxo"
|
||||
|
||||
msgid "Title"
|
||||
msgstr "Título"
|
||||
@@ -20404,7 +20404,7 @@ msgstr ""
|
||||
"DampingEnd <= 1)"
|
||||
|
||||
msgid "Cornering test"
|
||||
msgstr "Teste de curvas"
|
||||
msgstr "Teste de quinas"
|
||||
|
||||
msgid "SCV-V2"
|
||||
msgstr "SCV-V2"
|
||||
@@ -20416,11 +20416,11 @@ msgid "End: "
|
||||
msgstr "Final: "
|
||||
|
||||
msgid "Cornering settings"
|
||||
msgstr "Configurações de curvas"
|
||||
msgstr "Configurações de quinas"
|
||||
|
||||
msgid "Note: Lower values = sharper corners but slower speeds."
|
||||
msgstr ""
|
||||
"Nota: Valores mais baixos = cantos mais nítidos, mas velocidades mais lentas."
|
||||
"Nota: Valores mais baixos = quinas mais nítidas, mas velocidades mais lentas."
|
||||
|
||||
msgid ""
|
||||
"Marlin 2 Junction Deviation detected:\n"
|
||||
@@ -20453,7 +20453,7 @@ msgid ""
|
||||
"(0 <= Cornering <= %s)"
|
||||
msgstr ""
|
||||
"Por favor, insira valores válidos:\n"
|
||||
"(0 <= Curvas <= %s)"
|
||||
"(0 <= Quinas <= %s)"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "NOTE: High values may cause Layer shift (>%s)"
|
||||
@@ -22317,7 +22317,7 @@ msgid "Restart Later"
|
||||
msgstr "Reiniciar Depois"
|
||||
|
||||
msgid "NO RAMMING AT ALL"
|
||||
msgstr "SEM COMPACTAÇÃO"
|
||||
msgstr "SEM NENHUM MOLDEAMENTO"
|
||||
|
||||
msgid "Volumetric speed"
|
||||
msgstr "Velocidade volumétrica"
|
||||
@@ -22770,9 +22770,6 @@ msgstr ""
|
||||
"aumentar adequadamente a temperatura da mesa aquecida pode reduzir a "
|
||||
"probabilidade de empenamento?"
|
||||
|
||||
#~ msgid "BambuStudio warning"
|
||||
#~ msgstr "Aviso do Bambu Studio"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Zero first layer height is invalid.\n"
|
||||
#~ "\n"
|
||||
@@ -22789,30 +22786,12 @@ msgstr ""
|
||||
#~ "A posição da torre de preparo ultrapassou os limites da placa de "
|
||||
#~ "impressão e foi reposicionada para a borda válida mais próxima."
|
||||
|
||||
#~ msgid "Check for Update"
|
||||
#~ msgstr "Verificar Atualizações"
|
||||
|
||||
#~ msgid "Detect spaghetti failure(scattered lose filament)."
|
||||
#~ msgstr "Detectar falha de emaranhado (filamentos soltos e dispersos)."
|
||||
|
||||
#~ msgid "Rotate of view"
|
||||
#~ msgstr "Rotação da vista"
|
||||
|
||||
#~ msgid "Move of view"
|
||||
#~ msgstr "Movimento da vista"
|
||||
|
||||
#~ msgid "Zoom of view"
|
||||
#~ msgstr "Zoom da vista"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enabling both precise Z height and the prime tower may cause the size of "
|
||||
#~ "prime tower to increase. Do you still want to enable?"
|
||||
#~ msgstr ""
|
||||
#~ "Habilitar a altura Z precisa e a torre de preparo pode fazer com que o "
|
||||
#~ "tamanho da torre de preparo aumente. Deseja habilitar mesmo assim?"
|
||||
|
||||
#~ msgid "Extruders count"
|
||||
#~ msgstr "Número de extrusoras"
|
||||
#~ "Habilitar a altura Z precisa e a torre de preparação juntas pode causar "
|
||||
#~ "o aumento de tamanho da torre de preparo. Deseja habilitar mesmo assim?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Missing BambuSource component registered for media playing! Please re-"
|
||||
@@ -23100,11 +23079,6 @@ msgstr ""
|
||||
#~ msgid "Junction Deviation settings"
|
||||
#~ msgstr "Configurações de Desvio de Junção"
|
||||
|
||||
#~ msgid "Note: Lower values = sharper corners but slower speeds"
|
||||
#~ msgstr ""
|
||||
#~ "Nota: Valores mais baixos = cantos mais nítidos, mas velocidades mais "
|
||||
#~ "lentas"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Please input valid values:\n"
|
||||
#~ "(0 <= Junction Deviation < 1)"
|
||||
|
||||
+57
-10
@@ -928,16 +928,63 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
|
||||
for (size_t iia = 0; iia < islands_area.size(); ++iia)
|
||||
islands_area[iia].translate(plate_shift);
|
||||
|
||||
for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
|
||||
if (!iter->second.empty()) {
|
||||
brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||
};
|
||||
}
|
||||
for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
|
||||
if (!iter->second.empty()) {
|
||||
supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||
};
|
||||
const bool combine_brims = print.config().combine_brims.value;
|
||||
const bool is_by_object = (print.config().print_sequence == PrintSequence::ByObject);
|
||||
const bool can_combine_brims = combine_brims && !is_by_object;
|
||||
|
||||
if (!can_combine_brims) {
|
||||
// Orca: Generate brims separately for each object when multiple extruders are used
|
||||
for (auto iter = brimAreaMap.begin(); iter != brimAreaMap.end(); ++iter) {
|
||||
if (!iter->second.empty()) {
|
||||
brimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||
};
|
||||
}
|
||||
for (auto iter = supportBrimAreaMap.begin(); iter != supportBrimAreaMap.end(); ++iter) {
|
||||
if (!iter->second.empty()) {
|
||||
supportBrimMap.insert(std::make_pair(iter->first, makeBrimInfill(iter->second, print, islands_area)));
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Orca: Unified brim mode (non-sequential printing)
|
||||
ExPolygons all_brims_merged;
|
||||
std::vector<ObjectID> brim_object_ids;
|
||||
|
||||
// Add all object brims
|
||||
for (auto& [obj_id, brims] : brimAreaMap) {
|
||||
if (!brims.empty()) {
|
||||
expolygons_append(all_brims_merged, brims);
|
||||
brim_object_ids.push_back(obj_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_brims_merged.empty()) {
|
||||
// Merge all brims into a single continuous area
|
||||
all_brims_merged = union_ex(all_brims_merged);
|
||||
|
||||
// Apply a tiny morphological cleanup to reduce boolean-union micro-artifacts.
|
||||
const float brim_cleanup_delta = std::max(float(scaled_resolution), float(SCALED_EPSILON));
|
||||
all_brims_merged = offset2_ex(all_brims_merged, brim_cleanup_delta, -brim_cleanup_delta, jtRound, scaled_resolution);
|
||||
|
||||
// Generate infill once for the merged brim area.
|
||||
ExtrusionEntityCollection merged_brim = makeBrimInfill(all_brims_merged, print, islands_area);
|
||||
|
||||
// In unified mode, assign the merged brim to a deterministic carrier object.
|
||||
// Pick the first object in print order that actually contributed brim area.
|
||||
ObjectID carrier_id;
|
||||
bool carrier_found = false;
|
||||
for (const auto& [obj_id, _extruder] : objPrintVec) {
|
||||
if (std::find(brim_object_ids.begin(), brim_object_ids.end(), obj_id) != brim_object_ids.end()) {
|
||||
carrier_id = obj_id;
|
||||
carrier_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!carrier_found)
|
||||
carrier_id = brim_object_ids.front();
|
||||
|
||||
brimMap[carrier_id] = std::move(merged_brim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -224,6 +224,8 @@ public:
|
||||
iy += 1;
|
||||
assert(iy <= iyb);
|
||||
}
|
||||
if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
|
||||
return;
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
} while (ix != ixb || iy != iyb);
|
||||
@@ -245,6 +247,8 @@ public:
|
||||
iy -= 1;
|
||||
assert(iy >= iyb);
|
||||
}
|
||||
if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
|
||||
return;
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
} while (ix != ixb || iy != iyb);
|
||||
@@ -270,6 +274,8 @@ public:
|
||||
iy += 1;
|
||||
assert(iy <= iyb);
|
||||
}
|
||||
if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
|
||||
return;
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
} while (ix != ixb || iy != iyb);
|
||||
@@ -307,6 +313,8 @@ public:
|
||||
iy -= 1;
|
||||
assert(iy >= iyb);
|
||||
}
|
||||
if (ix < 0 || iy < 0 || ix >= (int64_t)m_cols || iy >= (int64_t)m_rows)
|
||||
return;
|
||||
if (! visitor(iy, ix))
|
||||
return;
|
||||
} while (ix != ixb || iy != iyb);
|
||||
|
||||
+65
-11
@@ -5011,6 +5011,39 @@ LayerResult GCode::process_layer(
|
||||
bool has_insert_wrapping_detection_gcode = false;
|
||||
|
||||
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
|
||||
// Orca: Print unified global brim before any object.
|
||||
// Only do this if `combine_brims` is enabled and we are printing by layer.
|
||||
if (first_layer && sequence_by_layer && m_config.combine_brims && !print.m_brimMap.empty()) {
|
||||
const ObjectID unified_object_id = [&]() -> ObjectID {
|
||||
ObjectID id;
|
||||
bool found = false;
|
||||
for (const auto& [obj_id, brim] : print.m_brimMap) {
|
||||
const bool has_printable_entities = std::any_of(brim.entities.begin(), brim.entities.end(),
|
||||
[](const ExtrusionEntity* ee) { return ee != nullptr; });
|
||||
if (!has_printable_entities)
|
||||
continue;
|
||||
if (found)
|
||||
return ObjectID();
|
||||
id = obj_id;
|
||||
found = true;
|
||||
}
|
||||
return found ? id : ObjectID();
|
||||
}();
|
||||
|
||||
if (unified_object_id.valid()) {
|
||||
const auto it = print.m_brimMap.find(unified_object_id);
|
||||
if (it != print.m_brimMap.end()) {
|
||||
this->set_origin(0., 0.);
|
||||
for (const ExtrusionEntity* ee : it->second.entities)
|
||||
if (ee != nullptr)
|
||||
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||
|
||||
// Mark brim as printed for this object to avoid per-object brim emission later.
|
||||
this->m_objsWithBrim.erase(unified_object_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int extruder_id : layer_tools.extruders)
|
||||
{
|
||||
if (print.config().skirt_type == stCombined && !print.skirt().empty())
|
||||
@@ -5122,19 +5155,37 @@ LayerResult GCode::process_layer(
|
||||
if (is_anything_overridden && print_wipe_extrusions == 0)
|
||||
gcode+="; PURGING FINISHED\n";
|
||||
|
||||
bool skirt_generated_for_current_print_z = false;
|
||||
|
||||
for (InstanceToPrint &instance_to_print : instances_to_print) {
|
||||
if (print.config().skirt_type == stPerObject &&
|
||||
!instance_to_print.print_object.object_skirt().empty() &&
|
||||
print.config().print_sequence == PrintSequence::ByLayer
|
||||
&&
|
||||
(layer.id() < print.config().skirt_height || print.config().draft_shield == DraftShield::dsEnabled))
|
||||
print.config().print_sequence == PrintSequence::ByLayer)
|
||||
{
|
||||
if (first_layer)
|
||||
m_skirt_done.clear();
|
||||
const Point& offset = instance_to_print.print_object.instances()[instance_to_print.instance_id].shift;
|
||||
gcode += generate_skirt(print, instance_to_print.print_object.object_skirt(), offset, instance_to_print.print_object.config().skirt_start_angle, layer_tools, layer, extruder_id);
|
||||
if (instances_to_print.size() > 1 && &instance_to_print != &*(instances_to_print.end() - 1))
|
||||
m_skirt_done.pop_back();
|
||||
const LayerToPrint& layer_to_print = layers[instance_to_print.layer_id];
|
||||
const Layer* skirt_layer = layer_to_print.object_layer;
|
||||
if (skirt_layer == nullptr && layer_to_print.support_layer != nullptr &&
|
||||
layer_to_print.support_layer->id() < layer_to_print.support_layer->object()->slicing_parameters().raft_layers()) {
|
||||
skirt_layer = layer_to_print.support_layer;
|
||||
}
|
||||
|
||||
if (skirt_layer != nullptr &&
|
||||
(skirt_layer->id() < print.config().skirt_height || print.config().draft_shield == DraftShield::dsEnabled)) {
|
||||
const bool skirt_first_layer = (skirt_layer->id() == 0 && std::abs(skirt_layer->bottom_z()) < EPSILON);
|
||||
if (skirt_first_layer)
|
||||
m_skirt_done.clear();
|
||||
|
||||
if (skirt_generated_for_current_print_z && !m_skirt_done.empty())
|
||||
m_skirt_done.pop_back();
|
||||
|
||||
const Point& offset = instance_to_print.print_object.instances()[instance_to_print.instance_id].shift;
|
||||
std::string skirt_gcode = generate_skirt(print, instance_to_print.print_object.object_skirt(), offset,
|
||||
instance_to_print.print_object.config().skirt_start_angle, layer_tools,
|
||||
*skirt_layer, extruder_id);
|
||||
if (!skirt_gcode.empty())
|
||||
skirt_generated_for_current_print_z = true;
|
||||
gcode += std::move(skirt_gcode);
|
||||
}
|
||||
}
|
||||
|
||||
const auto& inst = instance_to_print.print_object.instances()[instance_to_print.instance_id];
|
||||
@@ -5567,7 +5618,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
||||
|
||||
if (m_config.spiral_mode && !is_hole) {
|
||||
// if spiral vase, we have to ensure that all contour are in the same orientation.
|
||||
loop.make_counter_clockwise();
|
||||
if (m_config.wall_direction == WallDirection::CounterClockwise)
|
||||
loop.make_counter_clockwise();
|
||||
else
|
||||
loop.make_clockwise();
|
||||
}
|
||||
//if (loop.loop_role() == elrSkirt && (this->m_layer->id() % 2 == 1))
|
||||
// loop.reverse();
|
||||
@@ -5629,7 +5683,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
||||
// 1 - the currently printed external perimeter and 2 - the neighbouring internal perimeter.
|
||||
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter && region_perimeters.size() > 1) {
|
||||
const bool is_full_loop_ccw = loop.polygon().is_counter_clockwise();
|
||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0; // loop.make_counter_clockwise();
|
||||
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0;
|
||||
const double nozzle_diam = nozzle_diameter;
|
||||
|
||||
// note: previous & next are inverted to extrude "in the opposite direction, and we are "rewinding"
|
||||
|
||||
@@ -4772,17 +4772,21 @@ void GCodeProcessor::process_G29(const GCodeReader::GCodeLine& line)
|
||||
|
||||
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
// Emulate G1 retract, decrement G1 count as it's will be incremented in process_G1, but it's fake G1
|
||||
GCodeReader::GCodeLine g10;
|
||||
g10.set(Axis::E, -this->m_parser.config().retraction_length.get_at(m_extruder_id));
|
||||
g10.set(Axis::F, this->m_parser.config().retraction_speed.get_at(m_extruder_id) * 60);
|
||||
--m_g1_line_id;
|
||||
process_G1(g10);
|
||||
}
|
||||
|
||||
void GCodeProcessor::process_G11(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
// Emulate G1 unretract, decrement G1 count as it's will be incremented in process_G1, but it's fake G1
|
||||
GCodeReader::GCodeLine g11;
|
||||
g11.set(Axis::E, this->m_parser.config().retraction_length.get_at(m_extruder_id) + this->m_parser.config().retract_restart_extra.get_at(m_extruder_id));
|
||||
g11.set(Axis::F, this->m_parser.config().deretraction_speed.get_at(m_extruder_id) * 60);
|
||||
--m_g1_line_id;
|
||||
process_G1(g11);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ static bool detect_steep_overhang(const PrintRegionConfig *config,
|
||||
}
|
||||
|
||||
static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perimeter_generator, const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls,
|
||||
bool &steep_overhang_contour, bool &steep_overhang_hole)
|
||||
bool &steep_overhang_contour, bool &steep_overhang_hole, bool reverse_thin_wall_hole)
|
||||
{
|
||||
// loops is an arrayref of ::Loop objects
|
||||
// turn each one into an ExtrusionLoop object
|
||||
@@ -248,12 +248,24 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
||||
} else {
|
||||
const PerimeterGeneratorLoop &loop = loops[idx.first];
|
||||
assert(thin_walls.empty());
|
||||
ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour, steep_overhang_hole);
|
||||
const bool reverse_children_thin_wall_hole = loops.size() == 1 && loop.is_contour && loop.children.size() == 1 &&
|
||||
(!loop.children.front().is_contour) && loop.children.front().children.empty();
|
||||
ExtrusionEntityCollection children = traverse_loops(perimeter_generator, loop.children, thin_walls, steep_overhang_contour,
|
||||
steep_overhang_hole, reverse_children_thin_wall_hole);
|
||||
out.entities.reserve(out.entities.size() + children.entities.size() + 1);
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll.entities[idx.first]);
|
||||
coll.entities[idx.first] = nullptr;
|
||||
|
||||
eloop->make_counter_clockwise();
|
||||
if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) == (loop.is_contour || reverse_thin_wall_hole))
|
||||
eloop->make_counter_clockwise();
|
||||
else
|
||||
eloop->make_clockwise();
|
||||
|
||||
// Orca: Reverse print order for thin wall holes.
|
||||
if (reverse_thin_wall_hole) {
|
||||
std::reverse(out.entities.begin(), out.entities.end());
|
||||
}
|
||||
|
||||
eloop->inset_idx = loop.depth;
|
||||
if (loop.is_contour) {
|
||||
out.append(std::move(children.entities));
|
||||
@@ -511,7 +523,11 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
|
||||
if (!paths.empty()) {
|
||||
if (extrusion->is_closed) {
|
||||
ExtrusionLoop extrusion_loop(std::move(paths), pg_extrusion.is_contour ? elrDefault : elrHole);
|
||||
extrusion_loop.make_counter_clockwise();
|
||||
if ((perimeter_generator.config->wall_direction == WallDirection::CounterClockwise) ==
|
||||
(pg_extrusion.is_contour || pg_extrusions.size() == 2))
|
||||
extrusion_loop.make_counter_clockwise();
|
||||
else
|
||||
extrusion_loop.make_clockwise();
|
||||
// TODO: it seems in practice that ExtrusionLoops occasionally have significantly disconnected paths,
|
||||
// triggering the asserts below. Is this a problem?
|
||||
for (auto it = std::next(extrusion_loop.paths.begin()); it != extrusion_loop.paths.end(); ++it) {
|
||||
@@ -519,8 +535,11 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
|
||||
assert(std::prev(it)->polyline.last_point() == it->polyline.first_point());
|
||||
}
|
||||
assert(extrusion_loop.paths.front().first_point() == extrusion_loop.paths.back().last_point());
|
||||
|
||||
extrusion_coll.append(std::move(extrusion_loop));
|
||||
// Orca: Reverse the order of paths for thin wall holes. We define thin wall hole as a hole with only one perimeter.
|
||||
const bool thin_wall_hole = !pg_extrusion.is_contour && pg_extrusions.size() == 2;
|
||||
if (thin_wall_hole && perimeter_generator.config->wall_sequence != WallSequence::OuterInner)
|
||||
std::reverse(extrusion_coll.entities.begin(), extrusion_coll.entities.end());
|
||||
}
|
||||
else {
|
||||
// Because we are processing one ExtrusionLine all ExtrusionPaths should form one connected path.
|
||||
@@ -1106,7 +1125,7 @@ static void reorient_perimeters(ExtrusionEntityCollection &entities, bool steep_
|
||||
}
|
||||
|
||||
if (need_reverse && !isExternal) {
|
||||
eloop->make_clockwise();
|
||||
eloop->reverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1414,18 +1433,17 @@ void PerimeterGenerator::process_classic()
|
||||
// at this point, all loops should be in contours[0]
|
||||
bool steep_overhang_contour = false;
|
||||
bool steep_overhang_hole = false;
|
||||
const WallDirection wall_direction = config->wall_direction;
|
||||
if (wall_direction != WallDirection::Auto) {
|
||||
// Skip steep overhang detection if wall direction is specified
|
||||
if (!config->overhang_reverse) {
|
||||
// Skip steep overhang detection no reverse is specified
|
||||
steep_overhang_contour = true;
|
||||
steep_overhang_hole = true;
|
||||
}
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole);
|
||||
ExtrusionEntityCollection entities = traverse_loops(*this, contours.front(), thin_walls, steep_overhang_contour, steep_overhang_hole, false);
|
||||
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
|
||||
if (wall_direction != WallDirection::CounterClockwise) {
|
||||
if (config->overhang_reverse) {
|
||||
reorient_perimeters(entities, steep_overhang_contour, steep_overhang_hole,
|
||||
// Reverse internal only if the wall direction is auto
|
||||
this->config->overhang_reverse_internal_only && wall_direction == WallDirection::Auto);
|
||||
this->config->overhang_reverse_internal_only);
|
||||
}
|
||||
|
||||
// if brim will be printed, reverse the order of perimeters so that
|
||||
@@ -2444,18 +2462,15 @@ void PerimeterGenerator::process_arachne()
|
||||
|
||||
bool steep_overhang_contour = false;
|
||||
bool steep_overhang_hole = false;
|
||||
const WallDirection wall_direction = config->wall_direction;
|
||||
if (wall_direction != WallDirection::Auto) {
|
||||
// Skip steep overhang detection if wall direction is specified
|
||||
if (!config->overhang_reverse) {
|
||||
// Skip steep overhang detection no reverse is specified
|
||||
steep_overhang_contour = true;
|
||||
steep_overhang_hole = true;
|
||||
}
|
||||
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions, steep_overhang_contour, steep_overhang_hole); !extrusion_coll.empty()) {
|
||||
// All walls are counter-clockwise initially, so we don't need to reorient it if that's what we want
|
||||
if (wall_direction != WallDirection::CounterClockwise) {
|
||||
if (config->overhang_reverse) {
|
||||
reorient_perimeters(extrusion_coll, steep_overhang_contour, steep_overhang_hole,
|
||||
// Reverse internal only if the wall direction is auto
|
||||
this->config->overhang_reverse_internal_only && wall_direction == WallDirection::Auto);
|
||||
this->config->overhang_reverse_internal_only);
|
||||
}
|
||||
this->loops->append(extrusion_coll);
|
||||
}
|
||||
|
||||
@@ -910,7 +910,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"top_surface_speed", "support_speed", "support_object_xy_distance", "support_object_first_layer_gap", "support_interface_speed",
|
||||
"bridge_speed", "internal_bridge_speed", "gap_infill_speed", "travel_speed", "travel_speed_z", "initial_layer_speed",
|
||||
"outer_wall_acceleration", "initial_layer_acceleration", "top_surface_acceleration", "default_acceleration", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle", "skirt_height","single_loop_draft_shield", "draft_shield",
|
||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
|
||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "brim_ears_max_angle", "brim_ears_detection_length", "enable_support", "support_type", "support_threshold_angle", "support_threshold_overlap","enforce_support_layers",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
|
||||
"support_base_pattern", "support_base_pattern_spacing", "support_expansion", "support_style",
|
||||
// BBS
|
||||
|
||||
@@ -263,7 +263,6 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(WallSequence)
|
||||
|
||||
//Orca
|
||||
static t_config_enum_values s_keys_map_WallDirection{
|
||||
{ "auto", int(WallDirection::Auto) },
|
||||
{ "ccw", int(WallDirection::CounterClockwise) },
|
||||
{ "cw", int(WallDirection::Clockwise)},
|
||||
};
|
||||
@@ -1595,6 +1594,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("combine_brims", coBool);
|
||||
def->label = L("Combine brims");
|
||||
def->category = L("Support");
|
||||
def->tooltip = L("Combine multiple brims into one when they are close to each other. This can improve brim adhesion.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("brim_ears", coBool);
|
||||
def->label = L("Brim ears");
|
||||
def->category = L("Support");
|
||||
@@ -2020,16 +2026,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("wall_direction", coEnum);
|
||||
def->label = L("Wall loop direction");
|
||||
def->category = L("Quality");
|
||||
def->tooltip = L("The direction which the wall loops are extruded when looking down from the top.\n\nBy default all walls are extruded in counter-clockwise, unless Reverse on even is enabled. Set this to any option other than Auto will force the wall direction regardless of the Reverse on even.\n\nThis option will be disabled if spiral vase mode is enabled.");
|
||||
def->tooltip = L("The direction which the contour wall loops are extruded when looking down from the top.\nHoles are printed in the opposite direction to the contour to maintain alignment with layers whose contour polygons are incomplete and change direction, also partially forming the contour of a hole.\n\nThis option will be disabled if spiral vase mode is enabled.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<WallDirection>::get_enum_values();
|
||||
def->enum_values.push_back("auto");
|
||||
def->enum_values.push_back("ccw");
|
||||
def->enum_values.push_back("cw");
|
||||
def->enum_labels.push_back(L("Auto"));
|
||||
def->enum_labels.push_back(L("Counter clockwise"));
|
||||
def->enum_labels.push_back(L("Clockwise"));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<WallDirection>(WallDirection::Auto));
|
||||
def->set_default_value(new ConfigOptionEnum<WallDirection>(WallDirection::CounterClockwise));
|
||||
|
||||
def = this->add("extruder", coInt);
|
||||
def->gui_type = ConfigOptionDef::GUIType::i_enum_open;
|
||||
@@ -7788,6 +7792,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||
} else if (opt_key == "machine_switch_extruder_time") {
|
||||
opt_key = "machine_tool_change_time";
|
||||
}
|
||||
else if (opt_key == "wall_direction" && value == "auto") {
|
||||
value = "ccw";
|
||||
}
|
||||
|
||||
// Ignore the following obsolete configuration keys:
|
||||
static std::set<std::string> ignore = {
|
||||
|
||||
@@ -126,7 +126,6 @@ enum class WallSequence {
|
||||
// Orca
|
||||
enum class WallDirection
|
||||
{
|
||||
Auto,
|
||||
CounterClockwise,
|
||||
Clockwise,
|
||||
Count,
|
||||
@@ -1564,6 +1563,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionString, thumbnails))
|
||||
// BBS: move from PrintObjectConfig
|
||||
((ConfigOptionBool, independent_support_layer_height))
|
||||
((ConfigOptionBool, combine_brims))
|
||||
// SoftFever
|
||||
((ConfigOptionPercents, filament_shrink))
|
||||
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
||||
|
||||
@@ -327,7 +327,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
config->opt_int("enforce_support_layers") == 0 &&
|
||||
! config->opt_bool("detect_thin_wall") &&
|
||||
! config->opt_bool("overhang_reverse") &&
|
||||
config->opt_enum<WallDirection>("wall_direction") == WallDirection::Auto &&
|
||||
config->opt_enum<TimelapseType>("timelapse_type") == TimelapseType::tlTraditional &&
|
||||
!config->opt_bool("enable_wrapping_detection")))
|
||||
{
|
||||
@@ -342,7 +341,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
|
||||
new_conf.set_key_value("enforce_support_layers", new ConfigOptionInt(0));
|
||||
new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
|
||||
new_conf.set_key_value("overhang_reverse", new ConfigOptionBool(false));
|
||||
new_conf.set_key_value("wall_direction", new ConfigOptionEnum<WallDirection>(WallDirection::Auto));
|
||||
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
new_conf.set_key_value("enable_wrapping_detection", new ConfigOptionBool(false));
|
||||
sparse_infill_density = 0;
|
||||
@@ -661,8 +659,6 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_shell);
|
||||
toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_shell);
|
||||
|
||||
toggle_field("wall_direction", !has_spiral_vase);
|
||||
|
||||
// Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
|
||||
toggle_field("gap_infill_speed", have_perimeters);
|
||||
|
||||
@@ -706,6 +702,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
bool have_brim = (config->opt_enum<BrimType>("brim_type") != btNoBrim);
|
||||
toggle_field("brim_object_gap", have_brim);
|
||||
toggle_field("brim_use_efc_outline", have_brim);
|
||||
toggle_field("combine_brims", have_brim);
|
||||
bool have_brim_width = (config->opt_enum<BrimType>("brim_type") != btNoBrim) && config->opt_enum<BrimType>("brim_type") != btAutoBrim &&
|
||||
config->opt_enum<BrimType>("brim_type") != btPainted;
|
||||
toggle_field("brim_width", have_brim_width);
|
||||
@@ -905,8 +902,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
||||
|
||||
bool has_detect_overhang_wall = config->opt_bool("detect_overhang_wall");
|
||||
bool has_overhang_reverse = config->opt_bool("overhang_reverse");
|
||||
bool force_wall_direction = config->opt_enum<WallDirection>("wall_direction") != WallDirection::Auto;
|
||||
bool allow_overhang_reverse = !has_spiral_vase && !force_wall_direction;
|
||||
bool allow_overhang_reverse = !has_spiral_vase;
|
||||
toggle_line("overhang_reverse", allow_overhang_reverse);
|
||||
toggle_line("overhang_reverse_internal_only", allow_overhang_reverse && has_overhang_reverse);
|
||||
bool has_overhang_reverse_internal_only = config->opt_bool("overhang_reverse_internal_only");
|
||||
|
||||
@@ -3302,7 +3302,6 @@ void PartPlate::set_vase_mode_related_object_config(int obj_id) {
|
||||
new_conf.set_key_value("detect_thin_wall", new ConfigOptionBool(false));
|
||||
new_conf.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
new_conf.set_key_value("overhang_reverse", new ConfigOptionBool(false));
|
||||
new_conf.set_key_value("wall_direction", new ConfigOptionEnum<WallDirection>(WallDirection::Auto));
|
||||
auto applying_keys = global_config->diff(new_conf);
|
||||
|
||||
for (ModelObject* object : obj_ptrs) {
|
||||
|
||||
@@ -4809,7 +4809,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
"extruder_clearance_radius",
|
||||
"extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
||||
"nozzle_height", "skirt_type", "skirt_loops", "skirt_speed","min_skirt_length", "skirt_distance", "skirt_start_angle",
|
||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
|
||||
"brim_width", "brim_object_gap", "brim_use_efc_outline", "combine_brims", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "preferred_orientation",
|
||||
"enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_tower_skip_points", "prime_tower_enable_framework",
|
||||
"prime_tower_infill_gap", "prime_volume",
|
||||
"extruder_colour", "filament_colour", "filament_type", "material_colour", "printable_height", "extruder_printable_height", "printer_model", "printer_technology",
|
||||
|
||||
@@ -2659,6 +2659,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("brim_width", "others_settings_brim#width");
|
||||
optgroup->append_single_option_line("brim_object_gap", "others_settings_brim#brim-object-gap");
|
||||
optgroup->append_single_option_line("brim_use_efc_outline", "others_settings_brim#brim-use-efc-outline");
|
||||
optgroup->append_single_option_line("combine_brims", "others_settings_brim#combine-brims");
|
||||
optgroup->append_single_option_line("brim_ears_max_angle", "others_settings_brim#ear-max-angle");
|
||||
optgroup->append_single_option_line("brim_ears_detection_length", "others_settings_brim#ear-detection-radius");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user