Compare commits

..

4 Commits

Author SHA1 Message Date
Ian Chua
e9ea8a8eb7 remove diagnostic logging 2026-05-25 10:34:47 +08:00
Ian Chua
8c6f0b4b47 Merge branch 'main' into fix/cli-segfault 2026-05-25 10:15:00 +08:00
Ian Chua
1a2118f696 Merge branch 'main' into fix/cli-segfault 2026-05-21 15:38:33 +08:00
Ian Chua
899bbafc99 fix: cli painted segmentation crash with mismatched filament counts 2026-05-21 15:37:00 +08:00
46 changed files with 451 additions and 1951 deletions

View File

@@ -122,7 +122,7 @@ msgid "On highlighted overhangs only"
msgstr "Nur an hervorgehobenen Überhängen"
msgid "Erase all"
msgstr "Alles löschen"
msgstr ""
msgid "Highlight overhang areas"
msgstr "Bereiche mit Überhang hervorheben"
@@ -350,10 +350,10 @@ msgid "Fixed step drag"
msgstr "Fester Schritt ziehen"
msgid "Context Menu"
msgstr "Kontextmenü"
msgstr ""
msgid "Toggle Auto-Drop"
msgstr "Automatisches Absenken umschalten"
msgstr ""
msgid "Single sided scaling"
msgstr "Einseitige Skalierung"
@@ -509,10 +509,10 @@ msgid "Multiple"
msgstr "Mehrere"
msgid "Count"
msgstr "Anzahl"
msgstr ""
msgid "Gap"
msgstr "Spalt"
msgstr ""
msgid "Spacing"
msgstr "Abstand"
@@ -883,7 +883,7 @@ msgid "Advanced"
msgstr "Erweiterte Einstellungen"
msgid "Reset all options except the text and operation"
msgstr "Alle Optionen außer dem Text und der Operation zurücksetzen"
msgstr ""
msgid ""
"The text cannot be written using the selected font. Please try choosing a "
@@ -1805,16 +1805,16 @@ msgid "Info"
msgstr "Info"
msgid "Loading printer & filament profiles"
msgstr "Lade Drucker- und Filamentprofile"
msgstr ""
msgid "Creating main window"
msgstr "Erstelle Hauptfenster"
msgstr ""
msgid "Loading current preset"
msgstr "Lade aktuelles Preset"
msgstr ""
msgid "Showing main window"
msgstr "Zeige Hauptfenster"
msgstr ""
msgid ""
"The OrcaSlicer configuration file may be corrupted and cannot be parsed.\n"
@@ -1897,12 +1897,9 @@ msgid ""
"Please check your network connectivity\n"
"(HTTP %u)"
msgstr ""
"Verbindung zu OrcaCloud fehlgeschlagen.\n"
"Bitte überprüfen Sie Ihre Netzwerkverbindung\n"
"(HTTP %u)"
msgid "Cloud Error"
msgstr "Cloud-Fehler"
msgstr ""
msgid "Retrieving printer information, please try again later."
msgstr "Empfange Druckerinformationen, bitte später erneut versuchen."
@@ -6103,13 +6100,13 @@ msgid "Export"
msgstr "Exportieren"
msgid "Sync Presets"
msgstr "Presets synchronisieren"
msgstr ""
msgid "Pull and apply the latest presets from OrcaCloud"
msgstr "Die neuesten Presets von OrcaCloud abrufen und anwenden"
msgstr ""
msgid "You must be logged in to sync presets from cloud."
msgstr "Sie müssen angemeldet sein, um Presets aus der Cloud zu synchronisieren."
msgstr ""
msgid "Quit"
msgstr "Beenden"
@@ -6239,7 +6236,7 @@ msgid "Preset Bundle"
msgstr "Vorlagen-Bundle"
msgid "Syncing presets from cloud…"
msgstr "Synchronisiere Presets aus der Cloud…"
msgstr ""
msgid "Help"
msgstr "Hilfe"
@@ -8944,25 +8941,25 @@ msgid "If enabled, reverses the direction of zoom with mouse wheel."
msgstr "Wenn aktiviert, wird die Richtung des Zooms mit dem Mausrad umgekehrt."
msgid "Pan"
msgstr "Schwenken"
msgstr ""
msgid "Left Mouse Drag"
msgstr "Linke Maustaste drücken"
msgstr ""
msgid "Set the action that dragging the left mouse button should perform."
msgstr "Legen Sie die Aktion fest, die das Ziehen der linken Maustaste ausführen soll."
msgstr ""
msgid "Middle Mouse Drag"
msgstr "Mittlere Maustaste drücken"
msgstr ""
msgid "Set the action that dragging the middle mouse button should perform."
msgstr "Legen Sie die Aktion fest, die das Ziehen der mittleren Maustaste ausführen soll."
msgstr ""
msgid "Right Mouse Drag"
msgstr "Rechte Maustaste drücken"
msgstr ""
msgid "Set the action that dragging the right mouse button should perform."
msgstr "Legen Sie die Aktion fest, die das Ziehen der rechten Maustaste ausführen soll."
msgstr ""
msgid "Clear my choice on..."
msgstr "Meine Auswahl löschen bei ..."
@@ -8989,13 +8986,13 @@ msgstr ""
"der Datei."
msgid "Graphics"
msgstr "Grafik"
msgstr ""
msgid "Anti-aliasing"
msgstr "Kantenglättung"
msgstr ""
msgid "MSAA Multiplier"
msgstr "MSAA-Multiplikator"
msgstr ""
msgid ""
"Set the Multi-Sample Anti-Aliasing level.\n"
@@ -9007,19 +9004,12 @@ msgid ""
"\n"
"Requires application restart."
msgstr ""
"Stellen Sie die Stufe der Multi-Sample-Kantenglättung ein.\n"
"Höhere Werte führen zu glatteren Kanten, aber die Auswirkungen auf die "
"Leistung sind exponentiell.\n"
"Niedrigere Werte verbessern die Leistung auf Kosten von gezackten Kanten.\n"
"Wenn deaktiviert, wird empfohlen, FXAA zu aktivieren, um gezackte Kanten mit minimalen Auswirkungen auf die Leistung zu reduzieren.\n"
"\n"
"Erfordert einen Neustart der Anwendung."
msgid "Disabled"
msgstr "Deaktiviert"
msgid "FXAA post-processing"
msgstr "FXAA-Nachbearbeitung"
msgstr ""
msgid ""
"Applies Fast Approximate Anti-Aliasing as a screen-space pass.\n"
@@ -9027,34 +9017,26 @@ msgid ""
"\n"
"Takes effect immediately."
msgstr ""
"Führt Fast Approximate Anti-Aliasing als Bildschirmraum-Pass aus.\n"
"Nützlich, um die MSAA-Einstellung zu deaktivieren oder zu reduzieren, um die Leistung zu verbessern.\n"
"\n"
"ist sofort wirksam"
msgid "FPS"
msgstr "FPS"
msgstr ""
msgid "FPS cap"
msgstr "FPS-Begrenzung"
msgstr ""
msgid "(0 = unlimited)"
msgstr "(0 = unbegrenzt)"
msgstr ""
msgid ""
"Limits viewport frame rate to reduce GPU load and power usage.\n"
"Set to 0 for unlimited frame rate."
msgstr ""
"Begrenzt die Bildrate des Viewports, um die GPU-Auslastung und den "
"Energieverbrauch zu reduzieren.\n"
"Auf 0 setzen für unbegrenzte Bildrate."
msgid "Show FPS overlay"
msgstr "FPS-Overlay anzeigen"
msgstr ""
msgid "Displays current viewport FPS in the top-right corner."
msgstr "Zeigt die aktuelle FPS des Viewports in der oberen rechten Ecke an."
msgstr ""
msgid "Login region"
msgstr "Login region"
@@ -9225,17 +9207,13 @@ msgid "Skip AMS blacklist check"
msgstr "Überspringen der AMS Blacklist-Prüfung"
msgid "(Experimental) Keep painted feature after mesh change"
msgstr "(Experimentell) Behalte bemalte Funktionen nach Mesh-Änderung bei"
msgstr ""
msgid ""
"Attempt to keep painted features (color/seam/support/fuzzy etc.) after "
"changing the object mesh (such as cut/reload from disk/simplify/fix etc.)\n"
"Highly experimental! Slow and may create artifact."
msgstr ""
"Versuchen Sie, bemalte Funktionen (Farbe/Naht/Stütze/unscharf usw.) nach "
"Änderung des Objekt-Meshs (z. B. schneiden/neu laden von der Festplatte/vereinfachen/reparieren usw.) beizubehalten\n"
"Sehr experimentell! Langsam und kann Artefakte erzeugen."
msgid "Allow Abnormal Storage"
msgstr "Fehlerhaften Speicher zulassen"
@@ -10961,37 +10939,26 @@ msgid ""
" %s first layer %d %s, other layers %d %s\n"
" %s max delta %d %s, current delta %d %s\n"
msgstr ""
" - %s:\n"
" %s erste Schicht %d %s, andere Schichten %d %s\n"
" %s maximale Delta %d %s, aktuelle Delta %d %s\n"
msgid ""
"Some first-layer and other-layer temperature pairs exceed safety limits.\n"
msgstr "Einige Temperaturpaare für die erste und andere Schicht überschreiten die Sicherheitsgrenzen.\n"
msgstr ""
msgid ""
"\n"
"Invalid pairs:\n"
msgstr ""
"\n"
"Ungültige Paare:\n"
msgid ""
"\n"
"You can go back to edit values, or continue if this is intentional."
msgstr ""
"\n"
"Sie können zurückgehen, um die Werte zu bearbeiten, oder fortfahren, wenn dies "
"absichtlich ist."
msgid ""
"\n"
"\n"
"Continue anyway?"
msgstr ""
"\n"
"\n"
"Trotzdem fortfahren?"
msgid "Temperature Safety Check"
msgstr "Temperatur-Sicherheitsprüfung"
@@ -11075,10 +11042,6 @@ msgid ""
"\"%1%\"\n"
"and \"%2%\" will open without any changes."
msgstr ""
"Alle \"Neuer Wert\" Einstellungen in\n"
"\"%1%\"\n"
"werden gespeichert und \"%2%\" wird ohne Änderungen geöffnet."
msgid "Click the right mouse button to display the full text."
msgstr ""
@@ -11684,7 +11647,7 @@ msgid "Login"
msgstr "Anmelden"
msgid "Login failed. Please try again."
msgstr "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut."
msgstr ""
msgid "[Action Required] "
msgstr "[Aktion erforderlich] "
@@ -11724,16 +11687,16 @@ msgid "Global shortcuts"
msgstr "Globale Tastaturkürzel"
msgid "Pan View"
msgstr "Ansicht verschieben"
msgstr ""
msgid "Rotate View"
msgstr "Ansicht drehen"
msgstr ""
msgid "Middle mouse button"
msgstr "Mittlere Maustaste"
msgstr ""
msgid "Zoom View"
msgstr "Ansicht zoomen"
msgstr ""
msgid ""
"Auto orients selected objects or all objects. If there are selected objects, "
@@ -12636,8 +12599,6 @@ msgid ""
"The Hollow base pattern is not supported by this support type; Rectilinear "
"will be used instead."
msgstr ""
"Das Hohl-Basis-Muster wird von diesem Stütztyp nicht unterstützt; Stattdessen "
"wird das Rechteckmuster verwendet."
msgid ""
"Support enforcers are used but support is not enabled. Please enable support."
@@ -14885,16 +14846,16 @@ msgid "Auto For Match"
msgstr "Automatisch für Übereinstimmung"
msgid "Enable filament dynamic map"
msgstr "Dynamische Filamentzuordnung aktivieren"
msgstr ""
msgid "Enable dynamic filament mapping during print."
msgstr "Dynamische Filamentzuordnung während des Drucks aktivieren."
msgstr ""
msgid "Has filament switcher"
msgstr "Hat Filamentwechsler"
msgstr ""
msgid "Printer has a filament switcher hardware (e.g., AMS)."
msgstr "Der Drucker verfügt über eine Filamentwechsler-Hardware (z. B. AMS)."
msgstr ""
msgid "Flush temperature"
msgstr "Spültemperatur"
@@ -15415,7 +15376,7 @@ msgstr ""
"unterstützt."
msgid "Z-buckling bias optimization (experimental)"
msgstr "Z-Buckling-Bias-Optimierung (experimentell)"
msgstr ""
msgid ""
"Tightens the gyroid wave along the Z (vertical) axis at low infill density "
@@ -15424,11 +15385,6 @@ msgid ""
"~30% sparse infill density and above. Only applies when Sparse infill "
"pattern is set to Gyroid."
msgstr ""
"Strafft die Gyroid-Welle entlang der Z-Achse (vertikal) bei geringer Fülldichte, "
"um die effektive vertikale Säulenlänge zu verkürzen und die Z-Achsen-Kompressions-"
"Knickfestigkeit zu verbessern. Der Filamentverbrauch bleibt erhalten. Keine "
"Auswirkung bei ~30% einfacher Fülldichte und darüber. Gilt nur, wenn das einfache "
"Füllmuster auf Gyroid eingestellt ist."
msgid "Sparse infill pattern"
msgstr "Füllmuster"
@@ -16318,7 +16274,7 @@ msgstr ""
"bringen.Setze den Wert auf 0, um diese Funktion zu deaktivieren."
msgid "Minimum non-zero part cooling fan speed"
msgstr "Minimale nicht-null Lüftergeschwindigkeit für die Teilekühlung"
msgstr ""
msgid ""
"Some part-cooling fans cannot start spinning when commanded below a certain "
@@ -16337,11 +16293,6 @@ msgid ""
"below the one you know it can actually spool at.\n"
"Set to 0 to deactivate."
msgstr ""
"Einige Teilekühlventilatoren können nicht zu drehen beginnen, wenn sie unter einem bestimmten PWM-Arbeitszyklus befehligt werden. Wenn dieser Wert über 0 eingestellt ist, wird jeder nicht-null-Teilekühlventilatorbefehl auf mindestens diesen Prozentsatz angehoben, damit der Lüfter zuverlässig startet. Ein Lüfterbefehl von 0 (Lüfter aus) wird immer genau eingehalten. Diese Begrenzung wird nach jeder anderen Lüfterberechnung angewendet (Erstschicht-Ramp-up, Schichtzeit-Interpolation, Überhangs-/Brücken-/Stützstruktur-Schnittstellen-/Glättungsüberschreibungen), sodass die Skalierung weiterhin im Bereich [dieser Wert, 100%] erfolgt.\n"
"\n"
"Wenn Ihre Firmware den Lüfter bereits unter einem Schwellenwert deaktiviert (z.B. Klipper's [fan] off_below: 0.10 schaltet den Lüfter aus, wenn der befehligte Arbeitszyklus unter 10% liegt), sollten idealerweise dieser Wert und der Firmware-Schwellenwert auf denselben Wert eingestellt werden. Wenn sie übereinstimmen (z.B. off_below: 0.10 in Klipper und 10% hier), garantiert der Slicer, dass er nie einen nicht-null-Wert emittiert, den die Firmware stillschweigend fallen lässt, und der Lüfter nie einen Wert erhält, der unter dem Wert liegt, den er tatsächlich anfahren kann.\n"
"\n"
"Setze den Wert auf 0, um diese Funktion zu deaktivieren."
msgid "%"
msgstr "%"
@@ -18432,7 +18383,7 @@ msgid "Enable filament ramming"
msgstr "Erlaube Filamentrammen"
msgid "Tool change on wipe tower"
msgstr "Werkzeugwechsel auf dem Reinigungsturm"
msgstr ""
msgid ""
"Force the toolhead to travel to the wipe tower before issuing the tool "
@@ -18443,8 +18394,6 @@ msgid ""
"this option if you want the tool change to always be issued above the wipe "
"tower instead."
msgstr ""
"Erzwinge, dass der Werkzeugkopf zum Reinigungsturm fährt, bevor der Werkzeugwechselbefehl (Tx) ausgegeben wird. Nur relevant für Mehrfach-Extruder (Mehrfach-Werkzeugkopf) Drucker, die einen Typ-2-Reinigungsturm verwenden. Standardmäßig überspringt Orca die Fahrt auf Mehrfach-Werkzeugkopf-Maschinen, da die Firmware den Kopfwechsel übernimmt, was dazu führen kann, dass der Tx-Befehl über dem gedruckten Teil ausgegeben wird. Aktivieren Sie diese Option, wenn Sie möchten, dass der Werkzeugwechsel immer über dem Reinigungsturm ausgegeben wird."
msgid "No sparse layers (beta)"
msgstr "Keine dünnen Schichten (Beta)"
@@ -19396,7 +19345,7 @@ msgstr ""
"verschiedene Materialien aufeinandertreffen."
msgid "Cool down from interface boost during prime tower"
msgstr "Abkühlung von der Schnittstellen-Boost während des Reinigungsturms"
msgstr "^"
msgid ""
"When interface-layer temperature boost is active, set the nozzle back to "
@@ -22045,18 +21994,12 @@ msgid ""
"\n"
"Available nozzle profiles for this printer:"
msgstr ""
"\n"
"\n"
"Verfügbare Düsenprofile für diesen Drucker:"
msgid ""
"\n"
"\n"
"Choose YES to switch existing preset:"
msgstr ""
"\n"
"\n"
"Wählen Sie JA, um das vorhandene Profil zu wechseln:"
msgid "Printer Created Successfully"
msgstr "Drucker erfolgreich erstellt"
@@ -23265,16 +23208,16 @@ msgid "Detection radius"
msgstr "Erkennungsradius"
msgid "Selected"
msgstr "Ausgewählt"
msgstr ""
msgid "Auto-generate"
msgstr "Automatisch generieren"
msgstr ""
msgid "Generate brim ears using Max angle and Detection radius"
msgstr "Mausohren mit Maximalwinkel und Erkennungsradius generieren"
msgstr ""
msgid "Add or Select"
msgstr "Hinzufügen oder auswählen"
msgstr ""
msgid ""
"Warning: The brim type is not set to \"painted\", the brim ears will not "
@@ -23287,7 +23230,7 @@ msgid "Set the brim type of this object to \"painted\""
msgstr "Den Brim-Typ dieses Objekts auf \"bemalt\" setzen"
msgid "invalid brim ears"
msgstr "Ungültige Mausohren"
msgstr ""
msgid "Brim Ears"
msgstr "Mausohren"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{
"name": "OrcaFilamentLibrary",
"version": "02.03.02.60",
"version": "02.04.00.00",
"force_update": "0",
"description": "Orca Filament Library",
"filament_list": [
@@ -1507,118 +1507,6 @@
{
"name": "GreenGate3D PETG @System",
"sub_path": "filament/GreenGate3D/GreenGate3D PETG @System.json"
},
{
"name": "DREMC PLA+ @base",
"sub_path": "filament/DREMC/DREMC PLA+ @base.json"
},
{
"name": "DREMC PLA+ @System",
"sub_path": "filament/DREMC/DREMC PLA+ @System.json"
},
{
"name": "DREMC PETG @base",
"sub_path": "filament/DREMC/DREMC PETG @base.json"
},
{
"name": "DREMC PETG @System",
"sub_path": "filament/DREMC/DREMC PETG @System.json"
},
{
"name": "DREMC ABS @base",
"sub_path": "filament/DREMC/DREMC ABS @base.json"
},
{
"name": "DREMC ABS @System",
"sub_path": "filament/DREMC/DREMC ABS @System.json"
},
{
"name": "DREMC ABS+ @base",
"sub_path": "filament/DREMC/DREMC ABS+ @base.json"
},
{
"name": "DREMC ABS+ @System",
"sub_path": "filament/DREMC/DREMC ABS+ @System.json"
},
{
"name": "DREMC ASA @base",
"sub_path": "filament/DREMC/DREMC ASA @base.json"
},
{
"name": "DREMC ASA @System",
"sub_path": "filament/DREMC/DREMC ASA @System.json"
},
{
"name": "DREMC PA6-CF @base",
"sub_path": "filament/DREMC/DREMC PA6-CF @base.json"
},
{
"name": "DREMC PA6-CF @System",
"sub_path": "filament/DREMC/DREMC PA6-CF @System.json"
},
{
"name": "DREMC PA12-CF @base",
"sub_path": "filament/DREMC/DREMC PA12-CF @base.json"
},
{
"name": "DREMC PA12-CF @System",
"sub_path": "filament/DREMC/DREMC PA12-CF @System.json"
},
{
"name": "DREMC PET-CF @base",
"sub_path": "filament/DREMC/DREMC PET-CF @base.json"
},
{
"name": "DREMC PET-CF @System",
"sub_path": "filament/DREMC/DREMC PET-CF @System.json"
},
{
"name": "DREMC ABS-GF @base",
"sub_path": "filament/DREMC/DREMC ABS-GF @base.json"
},
{
"name": "DREMC ABS-GF @System",
"sub_path": "filament/DREMC/DREMC ABS-GF @System.json"
},
{
"name": "DREMC TPU 95A @base",
"sub_path": "filament/DREMC/DREMC TPU 95A @base.json"
},
{
"name": "DREMC TPU 95A @System",
"sub_path": "filament/DREMC/DREMC TPU 95A @System.json"
},
{
"name": "DREMC PPA-CF @base",
"sub_path": "filament/DREMC/DREMC PPA-CF @base.json"
},
{
"name": "DREMC PPA-CF @System",
"sub_path": "filament/DREMC/DREMC PPA-CF @System.json"
},
{
"name": "DREMC PLA+ HS @base",
"sub_path": "filament/DREMC/DREMC PLA HS @base.json"
},
{
"name": "DREMC PLA+ HS @System",
"sub_path": "filament/DREMC/DREMC PLA HS @System.json"
},
{
"name": "DREMC ASA CF @base",
"sub_path": "filament/DREMC/DREMC ASA CF @base.json"
},
{
"name": "DREMC ASA CF @System",
"sub_path": "filament/DREMC/DREMC ASA CF @System.json"
},
{
"name": "DREMC ASA GF @base",
"sub_path": "filament/DREMC/DREMC ASA GF @base.json"
},
{
"name": "DREMC ASA GF @System",
"sub_path": "filament/DREMC/DREMC ASA GF @System.json"
}
],
"process_list": [],

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS @System",
"inherits": "DREMC ABS @base",
"from": "system",
"setting_id": "DREMC003",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,35 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS @base",
"inherits": "fdm_filament_abs",
"from": "system",
"filament_id": "DREMC003",
"instantiation": "false",
"filament_cost": [
"24"
],
"filament_density": [
"1.06"
],
"filament_flow_ratio": [
"0.95"
],
"filament_shrink": [
"99.7"
],
"fan_max_speed": [
"20"
],
"overhang_fan_speed": [
"50"
],
"filament_max_volumetric_speed": [
"20"
],
"chamber_temperature": [
"60"
],
"filament_vendor": [
"DREMC"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS+ @System",
"inherits": "DREMC ABS+ @base",
"from": "system",
"setting_id": "DREMC004",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,26 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS+ @base",
"inherits": "fdm_filament_abs",
"from": "system",
"filament_id": "DREMC004",
"instantiation": "false",
"filament_cost": [
"24"
],
"filament_density": [
"1.06"
],
"filament_flow_ratio": [
"0.93"
],
"filament_shrink": [
"99.7"
],
"filament_max_volumetric_speed": [
"20"
],
"filament_vendor": [
"DREMC"
]
}

View File

@@ -1,15 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS-GF @System",
"inherits": "DREMC ABS-GF @base",
"from": "system",
"setting_id": "DREMC009",
"instantiation": "true",
"filament_long_retractions_when_cut": [
"1"
],
"filament_retraction_distances_when_cut": [
"18"
],
"compatible_printers": []
}

View File

@@ -1,44 +0,0 @@
{
"type": "filament",
"name": "DREMC ABS-GF @base",
"inherits": "fdm_filament_abs",
"from": "system",
"filament_id": "DREMC009",
"instantiation": "false",
"fan_cooling_layer_time": [
"12"
],
"fan_max_speed": [
"30"
],
"filament_cost": [
"40"
],
"filament_density": [
"1.12"
],
"filament_flow_ratio": [
"0.95"
],
"filament_shrink": [
"99.7"
],
"filament_max_volumetric_speed": [
"18"
],
"filament_type": [
"ABS-GF"
],
"filament_vendor": [
"DREMC"
],
"overhang_fan_speed": [
"30"
],
"overhang_fan_threshold": [
"10%"
],
"slow_down_layer_time": [
"4"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA @System",
"inherits": "DREMC ASA @base",
"from": "system",
"setting_id": "DREMC005",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,44 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA @base",
"inherits": "fdm_filament_asa",
"from": "system",
"filament_id": "DREMC005",
"instantiation": "false",
"eng_plate_temp": [
"110"
],
"eng_plate_temp_initial_layer": [
"110"
],
"filament_cost": [
"36"
],
"filament_density": [
"1.09"
],
"filament_flow_ratio": [
"0.94"
],
"filament_shrink": [
"99.7"
],
"filament_max_volumetric_speed": [
"15"
],
"filament_vendor": [
"DREMC"
],
"hot_plate_temp": [
"110"
],
"hot_plate_temp_initial_layer": [
"110"
],
"textured_plate_temp": [
"110"
],
"textured_plate_temp_initial_layer": [
"110"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA CF @System",
"inherits": "DREMC ASA CF @base",
"from": "system",
"setting_id": "DREMC012_00",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,50 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA CF @base",
"inherits": "fdm_filament_asa",
"from": "system",
"filament_id": "DREMC012",
"instantiation": "false",
"eng_plate_temp": [
"110"
],
"eng_plate_temp_initial_layer": [
"110"
],
"filament_cost": [
"48"
],
"filament_density": [
"1.09"
],
"filament_flow_ratio": [
"0.92"
],
"filament_shrink": [
"99.7"
],
"filament_max_volumetric_speed": [
"15"
],
"filament_vendor": [
"DREMC"
],
"hot_plate_temp": [
"110"
],
"hot_plate_temp_initial_layer": [
"110"
],
"textured_plate_temp": [
"110"
],
"textured_plate_temp_initial_layer": [
"110"
],
"nozzle_temperature": [
"265"
],
"nozzle_temperature_initial_layer": [
"265"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA GF @System",
"inherits": "DREMC ASA GF @base",
"from": "system",
"setting_id": "DREMC013_00",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,50 +0,0 @@
{
"type": "filament",
"name": "DREMC ASA GF @base",
"inherits": "fdm_filament_asa",
"from": "system",
"filament_id": "DREMC013",
"instantiation": "false",
"eng_plate_temp": [
"110"
],
"eng_plate_temp_initial_layer": [
"110"
],
"filament_cost": [
"36"
],
"filament_density": [
"1.12"
],
"filament_flow_ratio": [
"0.92"
],
"filament_shrink": [
"99.7"
],
"filament_max_volumetric_speed": [
"15"
],
"filament_vendor": [
"DREMC"
],
"hot_plate_temp": [
"110"
],
"hot_plate_temp_initial_layer": [
"110"
],
"textured_plate_temp": [
"110"
],
"textured_plate_temp_initial_layer": [
"110"
],
"nozzle_temperature": [
"270"
],
"nozzle_temperature_initial_layer": [
"270"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC PA12-CF @System",
"inherits": "DREMC PA12-CF @base",
"from": "system",
"setting_id": "DREMC007",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,59 +0,0 @@
{
"type": "filament",
"name": "DREMC PA12-CF @base",
"inherits": "fdm_filament_pa",
"from": "system",
"filament_id": "DREMC007",
"instantiation": "false",
"fan_cooling_layer_time": [
"15"
],
"fan_max_speed": [
"100"
],
"filament_cost": [
"105"
],
"filament_density": [
"1.06"
],
"filament_flow_ratio": [
"0.95"
],
"filament_max_volumetric_speed": [
"14"
],
"filament_type": [
"PA-CF"
],
"filament_vendor": [
"DREMC"
],
"full_fan_speed_layer": [
"2"
],
"nozzle_temperature": [
"290"
],
"nozzle_temperature_initial_layer": [
"290"
],
"nozzle_temperature_range_low": [
"260"
],
"overhang_fan_speed": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"temperature_vitrification": [
"131"
],
"textured_plate_temp": [
"80"
],
"textured_plate_temp_initial_layer": [
"80"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC PA6-CF @System",
"inherits": "DREMC PA6-CF @base",
"from": "system",
"setting_id": "DREMC006",
"instantiation": "true",
"compatible_printers": []
}

View File

@@ -1,53 +0,0 @@
{
"type": "filament",
"name": "DREMC PA6-CF @base",
"inherits": "fdm_filament_pa",
"from": "system",
"filament_id": "DREMC006",
"instantiation": "false",
"fan_cooling_layer_time": [
"15"
],
"filament_cost": [
"68"
],
"filament_density": [
"1.25"
],
"filament_flow_ratio": [
"0.95"
],
"filament_max_volumetric_speed": [
"12"
],
"filament_type": [
"PA6-CF"
],
"filament_vendor": [
"DREMC"
],
"nozzle_temperature": [
"270"
],
"nozzle_temperature_initial_layer": [
"270"
],
"nozzle_temperature_range_low": [
"260"
],
"overhang_fan_speed": [
"100"
],
"reduce_fan_stop_start_freq": [
"1"
],
"temperature_vitrification": [
"215"
],
"textured_plate_temp": [
"90"
],
"textured_plate_temp_initial_layer": [
"90"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC PET-CF @System",
"inherits": "DREMC PET-CF @base",
"from": "system",
"setting_id": "DREMC008",
"instantiation": "false",
"compatible_printers": []
}

View File

@@ -1,86 +0,0 @@
{
"type": "filament",
"name": "DREMC PET-CF @base",
"inherits": "fdm_filament_pet",
"from": "system",
"filament_id": "DREMC008",
"instantiation": "false",
"cool_plate_temp": [
"0"
],
"cool_plate_temp_initial_layer": [
"0"
],
"eng_plate_temp": [
"70"
],
"eng_plate_temp_initial_layer": [
"70"
],
"fan_cooling_layer_time": [
"242"
],
"fan_min_speed": [
"0"
],
"filament_cost": [
"70"
],
"filament_density": [
"1.3"
],
"filament_flow_ratio": [
"0.95"
],
"filament_max_volumetric_speed": [
"12"
],
"filament_type": [
"PET-CF"
],
"filament_vendor": [
"DREMC"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"nozzle_temperature": [
"300"
],
"nozzle_temperature_initial_layer": [
"300"
],
"nozzle_temperature_range_high": [
"300"
],
"nozzle_temperature_range_low": [
"270"
],
"required_nozzle_HRC": [
"40"
],
"supertack_plate_temp": [
"80"
],
"supertack_plate_temp_initial_layer": [
"80"
],
"slow_down_layer_time": [
"5"
],
"slow_down_min_speed": [
"10"
],
"temperature_vitrification": [
"147"
],
"textured_plate_temp": [
"70"
],
"textured_plate_temp_initial_layer": [
"70"
]
}

View File

@@ -1,15 +0,0 @@
{
"type": "filament",
"name": "DREMC PETG @System",
"inherits": "DREMC PETG @base",
"from": "system",
"setting_id": "DREMC002",
"instantiation": "false",
"filament_max_volumetric_speed": [
"20"
],
"nozzle_temperature_range_high": [
"270"
],
"compatible_printers": []
}

View File

@@ -1,59 +0,0 @@
{
"type": "filament",
"name": "DREMC PETG @base",
"inherits": "fdm_filament_pet",
"from": "system",
"filament_id": "DREMC002",
"instantiation": "false",
"cool_plate_temp": [
"0"
],
"cool_plate_temp_initial_layer": [
"0"
],
"eng_plate_temp": [
"70"
],
"eng_plate_temp_initial_layer": [
"70"
],
"fan_cooling_layer_time": [
"30"
],
"fan_max_speed": [
"90"
],
"fan_min_speed": [
"20"
],
"filament_flow_ratio": [
"0.95"
],
"filament_vendor": [
"DREMC"
],
"hot_plate_temp": [
"70"
],
"hot_plate_temp_initial_layer": [
"70"
],
"overhang_fan_speed": [
"50"
],
"overhang_fan_threshold": [
"10%"
],
"slow_down_layer_time": [
"12"
],
"slow_down_min_speed": [
"10"
],
"textured_plate_temp": [
"70"
],
"textured_plate_temp_initial_layer": [
"70"
]
}

View File

@@ -1,12 +0,0 @@
{
"type": "filament",
"name": "DREMC PLA+ HS @System",
"inherits": "DREMC PLA+ @base",
"from": "system",
"setting_id": "DREMC011",
"instantiation": "false",
"filament_max_volumetric_speed": [
"22"
],
"compatible_printers": []
}

View File

@@ -1,20 +0,0 @@
{
"type": "filament",
"name": "DREMC PLA+ HS @base",
"inherits": "fdm_filament_pla",
"from": "system",
"filament_id": "DREMC011",
"instantiation": "false",
"filament_cost": [
"26"
],
"filament_density": [
"1.25"
],
"filament_flow_ratio": [
"0.98"
],
"filament_vendor": [
"DREMC"
]
}

View File

@@ -1,12 +0,0 @@
{
"type": "filament",
"name": "DREMC PLA+ @System",
"inherits": "DREMC PLA+ @base",
"from": "system",
"setting_id": "DREMC001",
"instantiation": "false",
"filament_max_volumetric_speed": [
"18"
],
"compatible_printers": []
}

View File

@@ -1,20 +0,0 @@
{
"type": "filament",
"name": "DREMC PLA+ @base",
"inherits": "fdm_filament_pla",
"from": "system",
"filament_id": "DREMC001",
"instantiation": "false",
"filament_cost": [
"26"
],
"filament_density": [
"1.25"
],
"filament_flow_ratio": [
"0.98"
],
"filament_vendor": [
"DREMC"
]
}

View File

@@ -1,9 +0,0 @@
{
"type": "filament",
"name": "DREMC PPA-CF @System",
"inherits": "DREMC PPA-CF @base",
"from": "system",
"setting_id": "DREMC010",
"instantiation": "true",
"compatible_printers": []
}

View File

@@ -1,11 +0,0 @@
{
"type": "filament",
"name": "DREMC PPA-CF @base",
"inherits": "fdm_filament_ppa",
"from": "system",
"filament_id": "DREMC010",
"instantiation": "false",
"filament_vendor": [
"DREMC"
]
}

View File

@@ -1,12 +0,0 @@
{
"type": "filament",
"name": "DREMC TPU 95A @System",
"inherits": "DREMC TPU 95A @base",
"from": "system",
"setting_id": "DREMC010",
"instantiation": "false",
"filament_max_volumetric_speed": [
"6"
],
"compatible_printers": []
}

View File

@@ -1,23 +0,0 @@
{
"type": "filament",
"name": "DREMC TPU 95A @base",
"inherits": "fdm_filament_tpu",
"from": "system",
"filament_id": "DREMC010",
"instantiation": "false",
"filament_cost": [
"40"
],
"filament_density": [
"1.25"
],
"filament_vendor": [
"DREMC"
],
"nozzle_temperature": [
"230"
],
"nozzle_temperature_initial_layer": [
"230"
]
}

View File

@@ -2195,7 +2195,7 @@ std::vector<std::vector<ExPolygons>> segmentation_by_painting(const PrintObject
// Returns multi-material segmentation based on painting in multi-material segmentation gizmo
std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback) {
const size_t num_facets_states = print_object.print()->config().filament_colour.size() + 1;
const size_t num_facets_states = print_object.print()->config().filament_diameter.size() + 1;
const float max_width = float(print_object.config().mmu_segmented_region_max_width.value);
const float interlocking_depth = float(print_object.config().mmu_segmented_region_interlocking_depth.value);
const bool interlocking_beam = print_object.config().interlocking_beam.value;

View File

@@ -1703,46 +1703,30 @@ void PrintObject::detect_surfaces_type()
// Only iterate to the second-to-last layer, since we look at layer i+1.
if( (this->config().enable_extra_bridge_layer.value == eblApplyToAll) || (this->config().enable_extra_bridge_layer.value == eblExternalBridgeOnly)){
const size_t last = (m_layers.empty() ? 0 : m_layers.size() - 1);
// ORCA: Two-phase split (collect-then-apply) to eliminate a data race in the
// original single-phase parallel_for, where iteration `i` rewrote
// m_layers[i+1]->slices.surfaces via std::move while iteration `i+1` (running
// on an adjacent TBB block on another worker thread) was iterating that same
// Surfaces vector as its bot_surfs. Splitting into a read-only collect pass
// followed by a write-only apply pass removes the cross-iteration aliasing.
//
// Phase 1: read-only pass — collect each layer's stBottomBridge polygons into a
// per-layer cache. No surfaces are mutated, so concurrent reads are safe.
std::vector<Polygons> bridge_polys_per_layer(last);
tbb::parallel_for(tbb::blocked_range<size_t>(0, last), [this, region_id, &bridge_polys_per_layer](const tbb::blocked_range<size_t> &range) {
tbb::parallel_for( tbb::blocked_range<size_t>(0, last), [this, region_id](const tbb::blocked_range<size_t> &range) {
for (size_t i = range.begin(); i < range.end(); ++i) {
m_print->throw_if_canceled();
// Step 1: Find bridge polygons
// Current layer (i): Search for stBottomBridge polygons.
const Surfaces &bot_surfs = m_layers[i]->m_regions[region_id]->slices.surfaces;
// Next layer (i+1): The layer where stInternal polygons may be re-classified.
Surfaces &top_surfs = m_layers[i + 1]->m_regions[region_id]->slices.surfaces;
// Step 2: Collect the bridge polygons in the current layer region
Polygons polygons_bridge;
for (const Surface &sbot : bot_surfs) {
if (sbot.surface_type == stBottomBridge) {
polygons_append(bridge_polys_per_layer[i], to_polygons(sbot));
polygons_append(polygons_bridge, to_polygons(sbot));
}
}
}
});
// Phase 2: write pass — each iteration mutates only m_layers[i+1]->slices.surfaces
// and reads its bridge polygons from the precomputed cache. Different iterations
// never share a write target, so there is no aliasing between worker threads.
tbb::parallel_for( tbb::blocked_range<size_t>(0, last), [this, region_id, &bridge_polys_per_layer](const tbb::blocked_range<size_t> &range) {
for (size_t i = range.begin(); i < range.end(); ++i) {
m_print->throw_if_canceled();
// Step 1 + 2: pull the precomputed bridge polygons for the current source layer.
const Polygons &polygons_bridge = bridge_polys_per_layer[i];
// Step 3: Early termination of loop if no meaningfull bridge found
// No bridge polygons found, continue to the next layer
if (polygons_bridge.empty())
continue;
// Step 4: Bottom bridge polygons found - scan and create layer+1 bridge polygon
Surfaces &top_surfs = m_layers[i + 1]->m_regions[region_id]->slices.surfaces;
Surfaces new_surfaces;
new_surfaces.reserve(top_surfs.size());
@@ -1756,50 +1740,7 @@ void PrintObject::detect_surfaces_type()
// This would also skip generation of very short dual bridge layers (that are shorter than N perimeters), but these are unecessary as the bridge distance is
// We could reduce this slightly to account for innacurcies in the clipping operation.
// TODO: Monitor GitHub issues to check whether second bridge layers are ommited where they should be generated. If yes, reduce the filtering distance
// ORCA: Same-layer-top guard.
//
// Collect every stTop polygon present at layer i+1 (this region) and
// expand it by the same `offset_distance` used by the bridge filter
// above. Note that `offset_distance` here is the full wall-band
// distance for the region (external wall width + all configured
// internal wall widths, i.e. external + (wall_loops - 1) × internal),
// not a single perimeter width. Any candidate second-bridge area that
// falls under this expanded mask will be subtracted out below.
//
// Why this exists: detect_surfaces_type() classifies a layer's "top"
// surfaces as the geometry that is not covered by the layer above. Those
// stTop regions often have small stInternal islands embedded in them.
// The pre-existing wall-band filter (shrink_ex/offset_ex by
// offset_distance) is supposed to throw those tiny islands away, but
// its result is sensitive to Clipper's floating-point order of
// operations: on macOS ARM the filter eats them, on Windows/Intel it
// doesn't. Visible bridges then show up scattered across the printed
// top surface.
//
// Expanding stTop by offset_distance and subtracting it from the
// overlap makes the decision platform-independent: an island fully
// surrounded by stTop disappears regardless of which Clipper happens
// to be doing the math, while large stInternal regions away from the
// top survive intact (the expansion only nibbles the wall-band depth
// inward).
//
// Keep ExPolygons throughout so that any holes inside an stTop surface
// are offset with the correct sign (positive offset shrinks holes /
// grows the solid region). Using Polygons + expand() would treat the
// contour and each hole as independent polygons and could distort the
// mask.
ExPolygons same_layer_top_expanded;
{
ExPolygons same_layer_top;
for (const Surface &s : top_surfs) {
if (s.surface_type == stTop)
same_layer_top.push_back(s.expolygon);
}
if (! same_layer_top.empty())
same_layer_top_expanded = offset_ex(same_layer_top, offset_distance);
}
// For each surface in the layer above
for (Surface &s_up : top_surfs) {
// Only reclassify stInternal polygons (i.e. what will become later solid and sparse infill)
@@ -1814,13 +1755,7 @@ void PrintObject::detect_surfaces_type()
// Filter out the resulting candidate bridges based on size. First perform a shrink operation...
// ...followed by an expand operation to bring them back to the original size (positive offset)
overlap = offset_ex(shrink_ex(overlap, offset_distance), offset_distance);
// ORCA: subtract the expanded same-layer stTop mask (see comment above
// the mask construction). Drops stInternal islands fully surrounded by
// stTop at i+1 without affecting bridges that lie away from the top.
if (! same_layer_top_expanded.empty() && ! overlap.empty())
overlap = diff_ex(overlap, same_layer_top_expanded, ApplySafetyOffset::Yes);
// Now subtract the filtered new bridge layer from the remaining internal surfaces to create the new internal surface
ExPolygons remainder = diff_ex(p_up, overlap, ApplySafetyOffset::Yes);
@@ -2565,76 +2500,29 @@ void PrintObject::bridge_over_infill()
backup_surfaces[lidx] = {};
}
// ORCA: Two-phase split (collect-then-apply) to eliminate a data race in
// the original single-phase parallel_for, where iteration `lidx` read
// m_layers[lidx-1]->regions()->fill_surfaces (its lower_layer) to compute
// `lightning_fill`, while iteration `lidx-1`, on an adjacent TBB block,
// was concurrently std::move-ing / emplace_back-ing into that same
// SurfaceCollection.
//
// Semantic choice — read ORIGINAL surfaces in Phase 1:
// The lower_layer that iteration `lidx` looks at is the *current* layer
// for iteration `lidx-1`, which Phase 2 will modify. We therefore have to
// pick whether Phase 1 sees that layer's pre-modification or
// post-modification state. We deliberately use the original (pre-modification)
// state, for two reasons:
// 1. The gate is asking "does the layer below use lightning sparse
// infill?" — that's a property of the layer's configuration plus its
// original sparse-infill classification. Phase 2's edits only carve
// a small overhang-aligned slice of sparse into solid; they do not
// change whether the layer is using lightning. The realistic gate
// answer is the same either way.
// 2. Each layer's solid expansion is meant to give its OWN lower_layer
// something to anchor lightning lines onto. Cascading the gate
// across layers ("skip mine because the layer below already did
// some") would invert that intent and force a serial Phase 2.
// The original racy code didn't actually implement either choice
// consistently — it returned whichever bytes happened to be in the
// vector when the thread arrived. This split makes the behaviour
// defined, deterministic across runs and platforms, and equivalent to
// a clean sequential implementation that gathered all gates first and
// then applied modifications.
//
// Phase 1: read-only — for each layer, determine whether its lower_layer
// has any stInternal area inside a lightning-infill region. That's the
// sole purpose of `lightning_fill` in the original code: a gate. Capture
// it once into a per-layer bool, derived from the original (unmodified)
// surfaces, so the gate is platform-independent and order-independent.
std::vector<char> needs_lightning_expansion(this->layers().size(), 0);
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = this, &surfaces_by_layer,
&needs_lightning_expansion](tbb::blocked_range<size_t> r) {
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = this, &backup_surfaces,
&surfaces_by_layer](tbb::blocked_range<size_t> r) {
PRINT_OBJECT_TIME_LIMIT_MILLIS(PRINT_OBJECT_TIME_LIMIT_DEFAULT);
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
if (surfaces_by_layer.find(lidx) == surfaces_by_layer.end())
continue;
const Layer *layer = po->get_layer(lidx);
Layer *layer = po->get_layer(lidx);
const Layer *lower_layer = layer->lower_layer;
if (lower_layer == nullptr)
continue;
Polygons lightning_fill;
for (const LayerRegion *region : lower_layer->regions()) {
if (region->region().config().sparse_infill_pattern == ipLightning
&& ! region->fill_surfaces.filter_by_type(stInternal).empty()) {
needs_lightning_expansion[lidx] = 1;
break;
if (region->region().config().sparse_infill_pattern == ipLightning) {
Polygons lf = to_polygons(region->fill_surfaces.filter_by_type(stInternal));
lightning_fill.insert(lightning_fill.end(), lf.begin(), lf.end());
}
}
}
});
// Phase 2: write-only — each iteration mutates only m_layers[lidx]'s
// fill_surfaces and never reads any other layer's surfaces. Different
// iterations write to disjoint LayerRegion::fill_surfaces vectors, so
// there is no aliasing between worker threads.
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = this, &backup_surfaces,
&surfaces_by_layer,
&needs_lightning_expansion](tbb::blocked_range<size_t> r) {
PRINT_OBJECT_TIME_LIMIT_MILLIS(PRINT_OBJECT_TIME_LIMIT_DEFAULT);
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
if (! needs_lightning_expansion[lidx])
if (lightning_fill.empty())
continue;
Layer *layer = po->get_layer(lidx);
for (LayerRegion *region : layer->regions()) {
backup_surfaces[lidx][region] = std::move(
region->fill_surfaces); // Make backup copy by move!! so that pointers in candidate surfaces stay valid
@@ -3344,75 +3232,53 @@ void PrintObject::bridge_over_infill()
// === ORCA: Create a second internal bridge layer above the first bridge layer. ========================================================
// ======================================================================================================================================
if ( this->m_config.enable_extra_bridge_layer == eblApplyToAll || this->m_config.enable_extra_bridge_layer == eblInternalBridgeOnly) {
// ORCA: Two-phase to eliminate the same data race as the external-bridge
// pass in detect_surfaces_type().
//
// Phase 1: read-only — for each layer, collect its stInternalBridge polygons and
// the matching bridge angle into a per-layer cache.
struct LayerBridgeCache {
ExPolygons polys;
double angle = 0.0;
float offset_distance = 0.0f;
bool has_bridge = false;
};
// Guard against size_t underflow when the object has 0 or 1 layers — there is
// no "layer above" to receive an extra bridge, so the whole pass is a no-op.
const size_t last = (this->layers().size() < 2) ? 0 : this->layers().size() - 1;
std::vector<LayerBridgeCache> caches(this->layers().size());
tbb::parallel_for( tbb::blocked_range<size_t>(0, last), [this, &caches](const tbb::blocked_range<size_t>& r) {
for (size_t lidx = r.begin(); lidx < r.end(); ++lidx) {
// Process layers in parallel up to second-to-last
tbb::parallel_for( tbb::blocked_range<size_t>(0, this->layers().size() - 1), [this](const tbb::blocked_range<size_t>& r) {
for (size_t lidx = r.begin(); lidx < r.end(); ++lidx)
{
Layer* layer = this->get_layer(lidx);
LayerBridgeCache &cache = caches[lidx];
if (!layer->regions().empty())
cache.offset_distance = layer->regions().front()->flow(frSolidInfill).scaled_width();
// (A) Gather internal bridging surfaces in the current layer
ExPolygons bridging_current_layer;
double bridging_angle_current = 0.0;
bool found_any_bridge = false;
float offset_distance = 0.0f;
// Pick a region from which to retrieve the flow width
if (!layer->regions().empty())
offset_distance = layer->regions().front()->flow(frSolidInfill).scaled_width();
for (LayerRegion *region : layer->regions()) {
for (const Surface &surf : region->fill_surfaces.surfaces) {
if (surf.surface_type == stInternalBridge) {
cache.polys.push_back(surf.expolygon);
cache.angle = surf.bridge_angle; // last bridge angle on this layer wins, matching prior behaviour
cache.has_bridge = true;
bridging_current_layer.push_back(surf.expolygon);
bridging_angle_current = surf.bridge_angle; // Store the last bridging angle of the current print object
found_any_bridge = true;
}
}
}
if (!cache.has_bridge || cache.polys.empty()) {
cache.has_bridge = false;
continue;
}
// Shrink-expand to remove trivial bridging areas
cache.polys = offset_ex(shrink_ex(cache.polys, cache.offset_distance), cache.offset_distance);
if (cache.polys.empty())
cache.has_bridge = false;
}
});
// Phase 2: write — each iteration mutates only m_layers[lidx+1]->fill_surfaces and
// pulls its bridge polygons from the precomputed cache. Different iterations never
// touch the same fill_surfaces vector, so there is no aliasing between workers.
tbb::parallel_for( tbb::blocked_range<size_t>(0, last), [this, &caches](const tbb::blocked_range<size_t>& r) {
for (size_t lidx = r.begin(); lidx < r.end(); ++lidx)
{
const LayerBridgeCache &cache = caches[lidx];
// If no bridging in this layer, continue with the next
if (!cache.has_bridge || cache.polys.empty())
if (!found_any_bridge || bridging_current_layer.empty())
continue;
// (B) Shrink-expand to remove trivial bridging areas
bridging_current_layer = offset_ex( shrink_ex(bridging_current_layer, offset_distance), offset_distance );
if (bridging_current_layer.empty())
continue; // all bridging was trivial, continue with the next layer
// (C) If there is a next layer, identify overlapping stInternal & stInternalSolid areas and convert the overlap to stSecondInternalBridge
if (lidx + 1 < this->layers().size()) {
Layer* next_layer = this->get_layer(lidx + 1);
// second bridging angle is 90 degrees offset
double bridging_angle_second = bridging_angle_current + M_PI / 2.0;
double bridging_angle_second = cache.angle + M_PI / 2.0;
// Union the bridging polygons
ExPolygons bridging_union = union_safety_offset_ex(cache.polys);
const float offset_distance = cache.offset_distance;
ExPolygons bridging_union = union_safety_offset_ex(bridging_current_layer);
for (LayerRegion *next_region : next_layer->regions()) {
Surfaces next_new_surfaces;
Surfaces keep_surfaces;

View File

@@ -883,7 +883,6 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
double z = print_object.get_layer(int(range.begin()))->slice_z;
auto it_layer_range = layer_range_first(layer_ranges, z);
// BBS
const size_t num_extruders = print_object.print()->config().filament_diameter.size();
struct ByExtruder {
ExPolygons expolygons;
@@ -903,6 +902,7 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer.slice_z);
const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range;
// Gather per extruder expolygons.
const size_t num_extruders = segmentation[layer_id].size();
by_extruder.assign(num_extruders, ByExtruder());
by_region.assign(layer.region_count(), ByRegion());
bool layer_split = false;

View File

@@ -978,51 +978,12 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
return list;
}
// ORCA: Compute slope.normal_z for 3D overhang highlight directly from support settings.
// If support_threshold_angle is 0, use tree fallback angle (30 deg) for tree supports,
// and derive an equivalent angle from threshold overlap for normal supports.
float GLVolumeCollection::get_selection_support_normal_z() const
int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_support) const
{
const DynamicPrintConfig& glb_cfg = GUI::wxGetApp().preset_bundle->prints.get_edited_preset().config;
const auto& full_cfg = GUI::wxGetApp().preset_bundle->full_config();
const auto support_type = glb_cfg.opt_enum<SupportType>("support_type");
const int support_threshold_angle = glb_cfg.opt_int("support_threshold_angle");
double angle_rad;
if (support_threshold_angle > 0) {
// Match support generation: explicit threshold angles are treated as inclusive.
const int effective_support_threshold_angle = std::min(support_threshold_angle + 1, 89);
angle_rad = Geometry::deg2rad(static_cast<double>(effective_support_threshold_angle));
} else if (is_tree(support_type)) {
angle_rad = Geometry::deg2rad(30.0); // fallback value for tree supports
} else { // For normal supports, if the angle is set to 0, calculate normal_z from overlap.
const double layer_height = full_cfg.opt_float("layer_height");
const auto* nozzle_diameter_opt = full_cfg.option<ConfigOptionFloats>("nozzle_diameter");
const int wall_filament = full_cfg.opt_int("wall_filament");
const size_t nozzle_count = nozzle_diameter_opt->values.size();
const size_t wall_extruder_idx = (wall_filament > 0 && wall_filament <= static_cast<int>(nozzle_count))
? static_cast<size_t>(wall_filament - 1)
: 0; // Invalid extruder index falls back to extruder 1.
// Use wall extruder's nozzle diameter for better estimation of external perimeter width,
// which is more relevant to overhang printing than the default nozzle diameter.
const double nozzle_diameter = nozzle_diameter_opt->values[wall_extruder_idx];
double external_perimeter_width = full_cfg.get_abs_value("outer_wall_line_width", nozzle_diameter);
if (external_perimeter_width <= 0.0) {
external_perimeter_width = full_cfg.get_abs_value("line_width", nozzle_diameter);
if (external_perimeter_width <= 0.0)
external_perimeter_width = nozzle_diameter;
}
const double overlap_width = full_cfg.get_abs_value("support_threshold_overlap", external_perimeter_width);
const double lower_layer_offset = std::max(0.0, external_perimeter_width - overlap_width);
angle_rad = lower_layer_offset <= EPSILON ? Geometry::deg2rad(89.0) : std::atan(layer_height / lower_layer_offset);
}
return static_cast<float>(-std::cos(std::clamp(angle_rad, 0.0, Geometry::deg2rad(89.0))));
const DynamicPrintConfig& glb_cfg = GUI::wxGetApp().preset_bundle->prints.get_edited_preset().config;
enable_support = glb_cfg.opt_bool("enable_support");
int support_threshold_angle = glb_cfg.opt_int("support_threshold_angle");
return support_threshold_angle ;
}
//BBS: add outline drawing logic
@@ -1058,8 +1019,6 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
if (disable_cullface)
glsafe(::glDisable(GL_CULL_FACE));
const float support_normal_z = get_selection_support_normal_z();
for (GLVolumeWithIdAndZ& volume : to_render) {
#if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT
if (type == ERenderType::Transparent) {
@@ -1116,11 +1075,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
//use -1 ad a invalid type
shader->set_uniform("print_volume.type", -1);
}
bool enable_support;
int support_threshold_angle = get_selection_support_threshold_angle(enable_support);
float normal_z = -::cos(Geometry::deg2rad((float) support_threshold_angle));
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
shader->set_uniform("slope.actived", m_slope.isGlobalActive && !volume.first->is_modifier && !volume.first->is_wipe_tower);
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
shader->set_uniform("slope.normal_z", support_normal_z);
shader->set_uniform("slope.normal_z", normal_z);
#if ENABLE_ENVIRONMENT_MAP
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();

View File

@@ -488,7 +488,7 @@ public:
GLVolume* new_toolpath_volume(const ColorRGBA& rgba);
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba);
float get_selection_support_normal_z() const;
int get_selection_support_threshold_angle(bool&) const;
// Render the volumes by OpenGL.
//BBS: add outline drawing logic
void render(ERenderType type,

View File

@@ -338,21 +338,7 @@ void FilamentGroupPopup::OnRadioBtn(int idx)
}
}
void FilamentGroupPopup::OnTimer(wxTimerEvent &event)
{
#if __APPLE__
// On macOS, when moving cursor from slice button to this popup window,
// the popup window entering event is triggered first, then the slice button
// leaving event got triggered. So the timer is stopped first, then started
// again, causing the popup being dismissed immediately.
// To fix this, we check if cursor is still inside the popup window before
// dismissing.
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
if (this->GetClientRect().Contains(pos)) return;
#endif
Dismiss();
}
void FilamentGroupPopup::OnTimer(wxTimerEvent &event) { Dismiss(); }
void FilamentGroupPopup::Dismiss() {
m_active = false;

View File

@@ -4374,12 +4374,12 @@ void GUI_App::get_login_info(const std::string& provider/* = ORCA_CLOUD_PROVIDER
if (m_agent) {
if (m_agent->is_user_login(provider)) {
std::string login_cmd = m_agent->build_login_cmd(provider);
wxString strJS = wxString::Format("window.postMessage(%s)", from_u8(login_cmd));
wxString strJS = wxString::Format("window.postMessage(%s)", login_cmd);
GUI::wxGetApp().run_script(strJS);
} else {
m_agent->user_logout(false, provider);
std::string logout_cmd = m_agent->build_logout_cmd(provider);
wxString strJS = wxString::Format("window.postMessage(%s)", from_u8(logout_cmd));
wxString strJS = wxString::Format("window.postMessage(%s)", logout_cmd);
GUI::wxGetApp().run_script(strJS);
}
mainframe->m_webview->SetLoginPanelVisibility(true);

View File

@@ -121,7 +121,6 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CATE
{"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"), 1},
{"bottom_surface_density", L("Bottom Surface Density"), 1},
{"sparse_infill_density", "", 1},
{"fill_multiline", "", 1},
{"sparse_infill_pattern", "", 1},
{"lateral_lattice_angle_1", "", 1},
{"lateral_lattice_angle_2", "", 1},
@@ -573,51 +572,35 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
wxMenu* MenuFactory::append_submenu_add_handy_model(wxMenu* menu, ModelVolumeType type) {
auto sub_menu = new wxMenu;
for (auto &item : {L("Orca Cube"), L("OrcaSliced Combo"), L("Orca Tolerance Test"), L("3DBenchy"), L("Cali Cat"), L("Autodesk FDM Test"),
for (auto &item : {L("Orca Cube"), L("Orca Tolerance Test"), L("3DBenchy"), L("Cali Cat"), L("Autodesk FDM Test"),
L("Voron Cube"), L("Stanford Bunny"), L("Orca String Hell") }) {
append_menu_item(
sub_menu, wxID_ANY, _(item), "",
[type, item](wxCommandEvent&) {
std::vector<boost::filesystem::path> input_files;
bool is_stringhell = false;
std::vector<std::string> file_names;
bool arrange_after_import = false;
if (item == L("Orca Cube")){
file_names = { "OrcaCube_v2.drc", "OrcaPlug_v2.drc"};
arrange_after_import = true;
}
else if (item == L("OrcaSliced Combo"))
{
file_names = { "OrcaSliced.3mf", "OrcaCube_v2.drc", "OrcaPlug_v2.drc" };
arrange_after_import = true;
}
else if (item == L("Orca Tolerance Test"))
file_names = { "OrcaToleranceTest.drc" };
else if (item == L("3DBenchy"))
file_names = { "3DBenchy.drc" };
else if (item == L("Cali Cat"))
file_names = { "calicat.drc" };
else if (item == L("Autodesk FDM Test"))
file_names = { "ksr_fdmtest_v4.drc" };
else if (item == L("Voron Cube"))
file_names = { "Voron_Design_Cube_v7.drc" };
else if (item == L("Stanford Bunny"))
file_names = { "Stanford_Bunny.drc" };
else if (item == L("Orca String Hell")) {
file_names = { "Orca_stringhell.drc" };
std::string file_name = item;
if (file_name == L("Orca Cube"))
file_name = "OrcaCube_v2.3mf";
else if (file_name == L("Orca Tolerance Test"))
file_name = "OrcaToleranceTest.drc";
else if (file_name == L("3DBenchy"))
file_name = "3DBenchy.drc";
else if (file_name == L("Cali Cat"))
file_name = "calicat.drc";
else if (file_name == L("Autodesk FDM Test"))
file_name = "ksr_fdmtest_v4.drc";
else if (file_name == L("Voron Cube"))
file_name = "Voron_Design_Cube_v7.drc";
else if (file_name == L("Stanford Bunny"))
file_name = "Stanford_Bunny.drc";
else if (file_name == L("Orca String Hell")) {
file_name = "Orca_stringhell.drc";
is_stringhell = true;
} else
return;
input_files.reserve(file_names.size());
for (const auto& file_name : file_names)
input_files.push_back((boost::filesystem::path(Slic3r::resources_dir()) / "handy_models" / file_name));
input_files.push_back((boost::filesystem::path(Slic3r::resources_dir()) / "handy_models" / file_name));
plater()->load_files(input_files, LoadStrategy::LoadModel);
if (arrange_after_import) {
plater()->set_prepare_state(Job::PREPARE_STATE_MENU);
plater()->arrange();
}
// Suggest to change settings for stringhell
// This serves as mini tutorial for new users

View File

@@ -2448,7 +2448,7 @@ void TabPrint::build()
optgroup->append_single_option_line("sparse_infill_density", "strength_settings_infill#sparse-infill-density");
optgroup->append_single_option_line("fill_multiline", "strength_settings_infill#fill-multiline");
optgroup->append_single_option_line("sparse_infill_pattern", "strength_settings_infill#sparse-infill-pattern");
optgroup->append_single_option_line("gyroid_optimized", "strength_settings_patterns#gyroid-optimized");
optgroup->append_single_option_line("gyroid_optimized", "strength_settings_patterns#gyroid_optimized");
optgroup->append_single_option_line("infill_direction", "strength_settings_infill#direction");
optgroup->append_single_option_line("sparse_infill_rotate_template", "strength_settings_infill_rotation_template_metalanguage");
optgroup->append_single_option_line("skin_infill_density", "strength_settings_patterns#locked-zag");