mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-28 19:31:22 +00:00
Fix support interface semantics, gap handling, behavior; fix bottom interface generation for organic trees; fix non organic tree interfaces (#11812)
* Fix support interface semantics and gap handling Fix zero-gap interface detection and gap initialization for supports and raft. Ensures correct top/bottom contact semantics and avoids relying on default zero gaps. * Additional fixes and robustness improvements Fix incorrect coupling between top and bottom support interface spacing and density, ensuring bottom interfaces use their own parameters for smoothing and toolpath generation. Restore correct bottom interface generation for organic (tree) supports when a non-zero bottom Z gap is used, and preserve contacts even when base polygons are empty. Improve robustness of organic support slicing by fixing layer index drift and guarding against degenerate polygon boolean operations. * Typo and semantics fix differnt_support_interface_filament -> different_support_interface_filament soluble -> zero_top_z_gap * Fix non organic tree bottom support interface generation Slim tree bottom interface layer numbers were capped by the object's layer number beneath it. Fixed by refactoring the generation algorithm. * Fix non organic tree interlaced support generation Deterministic local interlaced support layers generation for non-organic tree support * Enable support interface multimaterial for non organic tree Enables mixed-material support interface behavior for non organic tree support type. * Fix tree support interface layer counts and contact handling - Correct non‑organic tree top interface layer budgeting so gaps don’t consume a layer (N stays N). - Remove the extra roof interface pass that was duplicating the 2nd layer. - Organic tree: use only the lowest contact footprint and avoid extra bottom‑contact extrusion so interface count matches the user setting. * Bugfixes (a lot) Many, many bugs fixed, majority edge-case but still not playing by the rule. Some of them: - on multilevel base, on very small level variations the support was capped to the topmost level height - non-organic tree had gaps for supports in a multilevel base situiation - independent support layer height had issues with support interfaces (base support beneath bottom interface, top contact layer sometimes missing) - organic tree had issues with small variation multi-level base - organic tree support with zero top Z distance could overlap support-material and interface-material paths when separate materials were used - many, many others (I lost track of them)
This commit is contained in:
@@ -14212,7 +14212,10 @@ msgstr ""
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
@@ -14983,13 +14986,16 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
|
|||||||
@@ -16647,10 +16647,14 @@ msgstr "Model d'impressora"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Distància Z de contacte de la Vora d'Adherència"
|
msgstr "Distància Z de contacte de la Vora d'Adherència"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Distància Z entre l'objecte i la Vora d'Adherència. S'ignorarà per a "
|
"Espai Z entre la vora d'Adherència i l'objecte. "
|
||||||
"interfície soluble"
|
"Si la distància Z superior del suport és 0, aquest valor s'ignora i l'objecte "
|
||||||
|
"s'imprimeix en contacte directe amb la vora d'Adherència (sense espai)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Expansió de la Vora d'Adherència"
|
msgstr "Expansió de la Vora d'Adherència"
|
||||||
@@ -17631,14 +17635,20 @@ msgstr "Ignora els voladissos petits que possiblement no requereixen suport."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Distància Z superior"
|
msgstr "Distància Z superior"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "La distància z entre la interfície de suport superior i l'objecte"
|
msgstr "Espai Z entre la part superior del suport i l'objecte."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Distància Z inferior"
|
msgstr "Distància Z inferior"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "La distància z entre la interfície de suport inferior i l'objecte"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Espai Z entre l'objecte i la part inferior del suport. "
|
||||||
|
"Si la distància Z superior del suport és 0 i la part inferior té capes d'interfície, aquest "
|
||||||
|
"valor s'ignora i el suport s'imprimeix en contacte directe amb l'objecte (sense espai)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Base del Suport/Vora d'Adherència"
|
msgstr "Base del Suport/Vora d'Adherència"
|
||||||
|
|||||||
@@ -16181,9 +16181,14 @@ msgstr "Varianta tiskárny"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Z vzdálenost kontaktu raftu"
|
msgstr "Z vzdálenost kontaktu raftu"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Z mezera mezi objektem a raftem. Ignorováno pro rozpustitelné rozhraní."
|
"Z mezera mezi raftem a objektem. "
|
||||||
|
"Pokud je Horní Z vzdálenost podpory 0, tato hodnota se ignoruje "
|
||||||
|
"a objekt se tiskne v přímém kontaktu s raftem (bez mezery)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Rozšíření raftu"
|
msgstr "Rozšíření raftu"
|
||||||
@@ -17134,14 +17139,20 @@ msgstr "Ignore small overhangs that possibly don't require support."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Horní vzdálenost v ose Z"
|
msgstr "Horní vzdálenost v ose Z"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Z mezera mezi horním rozhraním podpory a objektem."
|
msgstr "Z mezera mezi horním rozhraním podpory a objektem."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Spodní vzdálenost v ose Z"
|
msgstr "Spodní vzdálenost v ose Z"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Z mezera mezi spodním rozhraním podpory a objektem."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z mezera mezi spodním rozhraním podpory a objektem. "
|
||||||
|
"Pokud je Horní Z vzdálenost podpory 0 a spodek má vrstvy rozhraní, tato hodnota "
|
||||||
|
"se ignoruje a podpora se tiskne v přímém kontaktu s objektem (bez mezery)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Podpora/základ raftu"
|
msgstr "Podpora/základ raftu"
|
||||||
|
|||||||
@@ -16767,9 +16767,14 @@ msgstr "Druckervariante"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Z Abstand Objekt Druckbasis "
|
msgstr "Z Abstand Objekt Druckbasis "
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Z-Abstand zwischen Objekt und Druckbasis. Bei löslicher Oberfläche ignoriert"
|
"Z-Abstand zwischen Druckbasis (Raft) und Objekt. "
|
||||||
|
"Wenn der obere Z-Abstand der Stützen ist 0, wird dieser Wert ignoriert und das "
|
||||||
|
"Objekt wird in direktem Kontakt mit der Druckbasis (Raft) gedruckt (kein Abstand)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Druckbasis Erweiterung"
|
msgstr "Druckbasis Erweiterung"
|
||||||
@@ -17744,14 +17749,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Oberer Z-Abstand"
|
msgstr "Oberer Z-Abstand"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Der Z-Abstand zwischen der oberen Stütz-Schnittstelle und dem Objekt"
|
msgstr "Z-Abstand zwischen der Oberseite der Stützen und dem Objekt."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Unterer Z-Abstand"
|
msgstr "Unterer Z-Abstand"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Der Z-Abstand zwischen der unteren Stütz-Schnittstelle und dem Objekt"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z-Abstand zwischen dem Objekt und der Unterseite der Stützen. "
|
||||||
|
"Wenn der obere Z-Abstand der Stützen ist 0 und die Unterseite Schnittstellenschichten hat, wird dieser "
|
||||||
|
"Wert ignoriert und die Stützen werden in direktem Kontakt mit dem Objekt gedruckt (kein Abstand)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Stütz-/Basis-Objekt"
|
msgstr "Stütz-/Basis-Objekt"
|
||||||
|
|||||||
@@ -14527,10 +14527,13 @@ msgstr ""
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"This is the Z gap between an object and a raft. It is ignored for soluble "
|
"Z gap between raft and object. If Support Top Z Distance is 0, this value "
|
||||||
"interfaces."
|
"is ignored and the object is printed in direct contact with the raft (no gap)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -15325,14 +15328,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "This determines the Z gap between top support interfaces and objects."
|
msgstr "Z gap between the support's top and object."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -16713,10 +16713,14 @@ msgstr "Variante de la impresora"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Distancia Z de contacto de la balsa (base de impresión)"
|
msgstr "Distancia Z de contacto de la balsa (base de impresión)"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Espacio Z entre el objeto y la balsa (base de impresión). Se ignora con una "
|
"Espacio Z entre el objeto y la balsa (base de impresión). "
|
||||||
"interfaz soluble."
|
"Si la distancia Z superior del soporte es 0, este valor se ignora y el "
|
||||||
|
"objeto se imprime en contacto directo con la balsa (sin separación)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Expansión de la balsa (base de impresión)"
|
msgstr "Expansión de la balsa (base de impresión)"
|
||||||
@@ -17704,14 +17708,20 @@ msgstr "Ignorar pequeños voladizos que posiblemente no requieran soporte."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Distancia Z superior"
|
msgstr "Distancia Z superior"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "La distancia z entre la interfaz de soporte superior y el objeto."
|
msgstr "La distancia z entre la interfaz de soporte superior y el objeto."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Distancia Z inferior"
|
msgstr "Distancia Z inferior"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "La distancia z entre la interfaz de apoyo inferior y el objeto."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"La distancia z entre la interfaz de apoyo inferior y el objeto. "
|
||||||
|
"Si la distancia Z superior del soporte es 0 y la base tiene capas de interfaz, este valor "
|
||||||
|
"se ignora y el soporte se imprime en contacto directo con el objeto (sin separación)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Capa base/balsa"
|
msgstr "Capa base/balsa"
|
||||||
|
|||||||
@@ -16872,8 +16872,14 @@ msgstr "Variante de l’imprimante"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Distance Z de contact du radeau"
|
msgstr "Distance Z de contact du radeau"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "Écart en Z entre l'objet et le radeau. Ignoré pour l'interface soluble"
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Écart Z entre le radeau et l'objet. "
|
||||||
|
"Si la distance Z supérieure du support est 0, cette valeur est ignorée "
|
||||||
|
"et l'objet est imprimé en contact direct avec le radeau (sans écart)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Agrandissement du radeau"
|
msgstr "Agrandissement du radeau"
|
||||||
@@ -17870,14 +17876,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Distance Z supérieure"
|
msgstr "Distance Z supérieure"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "L'écart z entre l'interface de support supérieure et l'objet"
|
msgstr "Écart Z entre le haut du support et l'objet."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Distance Z inférieure"
|
msgstr "Distance Z inférieure"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "L'écart Z entre l'interface du support inférieur et l'objet"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Écart Z entre l'objet et le bas du support. "
|
||||||
|
"Si la distance Z supérieure du support est 0 et que le bas a des couches d'interface, cette "
|
||||||
|
"valeur est ignorée et le support est imprimé en contact direct avec l'objet (sans écart)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Support/base du radeau"
|
msgstr "Support/base du radeau"
|
||||||
|
|||||||
@@ -16520,10 +16520,14 @@ msgstr "Nyomtató változat"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Tutaj érintkezési Z-távolság"
|
msgstr "Tutaj érintkezési Z-távolság"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"This is the Z gap between an object and a raft. It is ignored for soluble "
|
"Z rés a tutaj és a tárgy között. "
|
||||||
"interfaces."
|
"Ha a támasz felső Z-távolsága 0, ez az érték figyelmen kívül lesz "
|
||||||
|
"hagyva és a tárgy közvetlenül a tutajon kerül nyomtatásra (rés nélkül)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Tutaj kibővítése"
|
msgstr "Tutaj kibővítése"
|
||||||
@@ -17510,19 +17514,24 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Z távolság"
|
msgstr "Z távolság"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Meghatározza a Z távolságot a felső támasz érintkező rétege és az objektum "
|
"Z rés a támasz teteje és a tárgy között."
|
||||||
"között."
|
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Alsó Z távolság"
|
msgstr "Alsó Z távolság"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "A Z távolság az alsó támasz érintkező rétege és az objektum között."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z rés a tárgy és a támasz alja között. "
|
||||||
|
"Ha a támasz felső Z-távolsága 0 és az alján vannak interfész rétegek, ez az érték "
|
||||||
|
"figyelmen kívül lesz hagyva, és a támasz közvetlenül a tárgyhoz lesz nyomtatva (rés nélkül)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Támaszték/tutaj alap"
|
msgstr "Támasz/tutaj alap"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Filament to print support base and raft. \"Default\" means no specific "
|
"Filament to print support base and raft. \"Default\" means no specific "
|
||||||
@@ -17558,7 +17567,7 @@ msgstr ""
|
|||||||
"letiltva."
|
"letiltva."
|
||||||
|
|
||||||
msgid "Support/raft interface"
|
msgid "Support/raft interface"
|
||||||
msgstr "Támaszték/tutaj csatlakozófelület"
|
msgstr "Támasz/tutaj interfész"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Filament to print support interface. \"Default\" means no specific filament "
|
"Filament to print support interface. \"Default\" means no specific filament "
|
||||||
|
|||||||
@@ -16748,10 +16748,14 @@ msgstr "Variante stampante"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Distanza Z di contatto zattera"
|
msgstr "Distanza Z di contatto zattera"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Indica lo spazio Z tra oggetto e zattera. Viene ignorato per le interfacce "
|
"Spazio Z tra zattera e oggetto. "
|
||||||
"di supporto solubili."
|
"Se la distanza Z superiore del supporto è 0, questo valore viene ignorato e "
|
||||||
|
"l'oggetto viene stampato a contatto diretto con la zattera (senza spazio)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Espansione della zattera"
|
msgstr "Espansione della zattera"
|
||||||
@@ -17745,16 +17749,21 @@ msgstr "Ignora i piccoli sbalzi che potrebbero non richiedere supporto."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Distanza Z superiore"
|
msgstr "Distanza Z superiore"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Determina lo spazio Z tra l'interfaccia di supporto superiore e l'oggetto."
|
"Spazio Z tra la parte superiore del supporto e l'oggetto."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Distanza Z inferiore"
|
msgstr "Distanza Z inferiore"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Determina lo spazio Z tra l'interfaccia di supporto inferiore e l'oggetto."
|
"Spazio Z tra l'oggetto e la base del supporto. "
|
||||||
|
"Se la distanza Z superiore del supporto è 0 e la base ha strati di interfaccia, questo valore "
|
||||||
|
"viene ignorato e il supporto viene stampato a contatto diretto con l'oggetto (senza spazio)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Base supporto/zattera"
|
msgstr "Base supporto/zattera"
|
||||||
|
|||||||
@@ -15234,10 +15234,14 @@ msgstr "プリンターバリエーション"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "ラフト接触面Z間隔"
|
msgstr "ラフト接触面Z間隔"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"ラフトとオブジェクトのZ方向の間隔。可溶性材料を使用する場合この設定が無効で"
|
"ラフトとオブジェクトの間のZ隙間。"
|
||||||
"す。"
|
"サポート上面Z距離が0の場合、この値は無視され、"
|
||||||
|
"オブジェクトはラフトに直接接触して印刷されます(隙間なし)。"
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "ラフト拡張"
|
msgstr "ラフト拡張"
|
||||||
@@ -16046,14 +16050,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "トップ面とのZ間隔"
|
msgstr "トップ面とのZ間隔"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "サポート接触面とオブジェクトのZ方向の間隔"
|
msgstr "サポート上面とオブジェクトの間のZ隙間。"
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "底面とのZ間隔"
|
msgstr "底面とのZ間隔"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "サポート底面とオブジェクトのZ方向間隔"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"オブジェクトとサポート下面の間のZ隙間。"
|
||||||
|
"サポート上面Z距離が0で、下面にインターフェース層がある場合、"
|
||||||
|
"この値は無視され、サポートはオブジェクトに直接接触して印刷されます(隙間なし)。"
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -15509,8 +15509,14 @@ msgstr "프린터 변형"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "라프트 접점 Z 거리"
|
msgstr "라프트 접점 Z 거리"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "객체와 라프트 사이의 Z 거리. 가용성 재료의 접점은 무시됨"
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"래프트와 객체 사이의 Z 간격. "
|
||||||
|
"서포트 상단 Z 거리가 0이면 이 값은 무시되고 "
|
||||||
|
"객체는 래프트에 직접 접촉하여 출력됩니다(간격 없음)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "라프트 확장"
|
msgstr "라프트 확장"
|
||||||
@@ -16426,14 +16432,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "상단 Z 거리"
|
msgstr "상단 Z 거리"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "서포트 상단과 객체 접점의 간격"
|
msgstr "서포트 상단과 객체 사이의 Z 간격."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "하단 Z 거리"
|
msgstr "하단 Z 거리"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "서포트 하단과 객체 접점의 간격"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"객체와 서포트 하단 사이의 Z 간격. "
|
||||||
|
"서포트 상단 Z 거리가 0이고 하단에 인터페이스 레이어가 있으"
|
||||||
|
"면 이 값은 무시되고 서포트가 객체에 직접 접촉하여 출력됩니다(간격 없음)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "서포트/라프트 기본"
|
msgstr "서포트/라프트 기본"
|
||||||
|
|||||||
@@ -16435,10 +16435,14 @@ msgstr "Spausdintuvo variantas"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Platformos kontakto Z atstumas"
|
msgstr "Platformos kontakto Z atstumas"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Z tarpas tarp objekto ir platformos. Į jį neatsižvelgiama tirpių sąsajų "
|
"Z tarpas tarp platformos ir objekto. "
|
||||||
"atveju."
|
"Jei viršutinis atramos Z atstumas yra 0, ši reikšmė ignoruojama ir "
|
||||||
|
"objektas spausdinamas tiesiogiai kontaktuojant su platforma (be tarpo)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Platformos išplėtimas"
|
msgstr "Platformos išplėtimas"
|
||||||
@@ -17408,14 +17412,20 @@ msgstr "Ignore small overhangs that possibly don't require support."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Viršutinis Z atstumas"
|
msgstr "Viršutinis Z atstumas"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Taip nustatomas Z tarpas tarp viršutinių atramų sąsajų ir objektų."
|
msgstr "Z tarpas tarp atramos viršaus ir objekto."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Apatinis Z atstumas"
|
msgstr "Apatinis Z atstumas"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Z tarpas tarp apatinės atramos sąsajos ir objekto."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z tarpas tarp objekto ir atramos apačios. "
|
||||||
|
"Jei viršutinis atramos Z atstumas yra 0 ir apačioje yra sąsajos sluoksniai, ši reikšmė "
|
||||||
|
"ignoruojama ir atrama spausdinama tiesiogiai kontaktuojant su objektu (be tarpo)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Atraminis ir (arba) platformos pagrindas"
|
msgstr "Atraminis ir (arba) platformos pagrindas"
|
||||||
|
|||||||
@@ -16429,10 +16429,14 @@ msgstr "Printervariant"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Vlot (raft) contact Z afstand:"
|
msgstr "Vlot (raft) contact Z afstand:"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dit is de Z-afstand tussen een object en een raft. Het wordt genegeerd voor "
|
"Z-gap tussen het vlot en het object. "
|
||||||
"oplosbare materialen."
|
"Als de bovenste Z-afstand van de ondersteuning 0 is, wordt deze waarde "
|
||||||
|
"genegeerd en wordt het object direct in contact met het vlot geprint (geen gap)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Vlot (raft) expansie"
|
msgstr "Vlot (raft) expansie"
|
||||||
@@ -17407,15 +17411,21 @@ msgstr "Ignore small overhangs that possibly don't require support."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Top Z afstand"
|
msgstr "Top Z afstand"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dit bepaald de Z-afstand tussen de bovenste support interfaces en het object."
|
"Z-gap tussen de bovenkant van de ondersteuning en het object."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Onderste Z-afstand"
|
msgstr "Onderste Z-afstand"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "De z-opening tussen de onderste ondersteuningsinterface en het object"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z-gap tussen het object en de onderkant van de ondersteuning. "
|
||||||
|
"Als de bovenste Z-afstand van de ondersteuning 0 is en de onderkant interfacerlagen heeft, wordt "
|
||||||
|
"deze waarde genegeerd en wordt de ondersteuning direct in contact met het object geprint (geen gap)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Support/raft base"
|
msgstr "Support/raft base"
|
||||||
|
|||||||
@@ -15876,10 +15876,14 @@ msgstr "Wariant drukarki"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Odległość Z kontaktu z tratwą"
|
msgstr "Odległość Z kontaktu z tratwą"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dystans między modelem, a raftem, mierzony w poziomie. Ignorowany dla "
|
"Odstęp Z między tratwą a obiektem. "
|
||||||
"rozpuszczalnych warstw łączących"
|
"Jeśli górny odstęp Z podpór wynosi 0, ta wartość jest ignorowana i "
|
||||||
|
"obiekt jest drukowany w bezpośrednim kontakcie z tratwą (bez odstępu)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Rozszerzenie tratwy"
|
msgstr "Rozszerzenie tratwy"
|
||||||
@@ -16846,14 +16850,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Odstęp góry w osi Z"
|
msgstr "Odstęp góry w osi Z"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Odstęp osi Z między górną warstwą łączącą podporę z obiektem"
|
msgstr "Odstęp Z między górą podpór a obiektem."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Odstęp spodu w osi Z"
|
msgstr "Odstęp spodu w osi Z"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Odległość w osi Z między dolną warstwą łączącyą a obiektem"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Odstęp Z między obiektem a dołem podpór. "
|
||||||
|
"Jeśli górny odstęp Z podpór wynosi 0 i dół ma warstwy interfejsu, ta wartość jest "
|
||||||
|
"ignorowana, a podpory są drukowane w bezpośrednim kontakcie z obiektem (bez odstępu)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Podstawa podpory/tratwy"
|
msgstr "Podstawa podpory/tratwy"
|
||||||
|
|||||||
@@ -16596,8 +16596,14 @@ msgstr "Variante da impressora"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Distância Z de contato da jangada"
|
msgstr "Distância Z de contato da jangada"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "Vão Z entre o objeto e a jangada. Ignorado para interface solúvel."
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Espaço Z entre a balsa e o objeto. "
|
||||||
|
"Se a Distância Z Superior do Suporte for 0, este valor é ignorado "
|
||||||
|
"e o objeto é impresso em contato direto com a balsa (sem espaço)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Expansão da jangada"
|
msgstr "Expansão da jangada"
|
||||||
@@ -17575,14 +17581,20 @@ msgstr "Ignorar pequenas saliências que possivelmente não requerem suporte."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Distância Z superior"
|
msgstr "Distância Z superior"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "O vão Z entre a interface superior de suporte e o objeto."
|
msgstr "Espaço Z entre o topo do suporte e o objeto."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Distância Z inferior"
|
msgstr "Distância Z inferior"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "O vão Z entre a interface inferior de suporte e o objeto."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Espaço Z entre o objeto e a base do suporte. "
|
||||||
|
"Se a Distância Z Superior do Suporte for 0 e a base tiver camadas de interface, este "
|
||||||
|
"valor é ignorado e o suporte é impresso em contato direto com o objeto (sem espaço)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Base de suporte/jangada"
|
msgstr "Base de suporte/jangada"
|
||||||
|
|||||||
@@ -16957,10 +16957,14 @@ msgstr "Модификация принтера"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Зазор под моделью"
|
msgstr "Зазор под моделью"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Вертикальное расстояние между подложкой и моделью. Значение игнорируется при "
|
"Вертикальное расстояние между подложкой и моделью. "
|
||||||
"выборе растворимого материала."
|
"Если зазор поддержки сверху равен 0, это значение игнорируется, "
|
||||||
|
"и модель печатается в прямом контакте с подложкой (без зазора)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Расширение подложки"
|
msgstr "Расширение подложки"
|
||||||
@@ -18050,16 +18054,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Зазор поддержки сверху"
|
msgstr "Зазор поддержки сверху"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr "Вертикальное расстояние между связующим слоем поддержки сверху и моделью."
|
||||||
"Вертикальное расстояние между связующим слоем поддержки сверху и моделью."
|
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Зазор поддержки снизу"
|
msgstr "Зазор поддержки снизу"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Вертикальное расстояние между связующим слоем поддержки снизу и моделью. "
|
"Вертикальное расстояние между связующим слоем поддержки снизу и моделью. "
|
||||||
|
"Если зазор поддержки сверху равен 0 и снизу есть интерфейсные слои, это значение "
|
||||||
|
"игнорируется, и поддержка печатается в прямом контакте с моделью (без зазора)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Поддержка/подложка"
|
msgstr "Поддержка/подложка"
|
||||||
|
|||||||
@@ -16258,10 +16258,14 @@ msgstr "Printer variant"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Raft kontakt Z avstånd"
|
msgstr "Raft kontakt Z avstånd"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Där finns Z mellanrum mellan ett objekt och en raft. Detta ignoreras för "
|
"Z-gapet mellan raften och objektet. "
|
||||||
"lösliga gränssnitt"
|
"Om Topp Z-distans är 0 ignoreras detta värde och objektet "
|
||||||
|
"skrivs ut i direkt kontakt med raften (utan mellanrum)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Raft expansion"
|
msgstr "Raft expansion"
|
||||||
@@ -17222,15 +17226,20 @@ msgstr "Ignore small overhangs that possibly don't require support."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Topp Z-distans"
|
msgstr "Topp Z-distans"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Detta bestämmer Z-avståndet mellan det övre support gränssnittet och objektet"
|
"Z-gapet mellan supportens topp och objektet."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Nedre Z-avstånd"
|
msgstr "Nedre Z-avstånd"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Z-gapet mellan botten support och objektets anläggningsyta"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr "Z-gapet mellan objektet och supportens botten. "
|
||||||
|
"Om Topp Z-distans är 0 och botten har gränssnittslager ignoreras detta "
|
||||||
|
"värde och supporten skrivs ut i direkt kontakt med objektet (utan mellanrum)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Support/raft bas"
|
msgstr "Support/raft bas"
|
||||||
|
|||||||
@@ -14490,8 +14490,14 @@ msgstr "Yazıcı çeşidi"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Raft kontak Z mesafesi"
|
msgstr "Raft kontak Z mesafesi"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "Nesne ve raft arasındaki Z boşluğu. Çözünür arayüz için göz ardı edildi."
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Sal ile nesne arasındaki Z boşluğu. "
|
||||||
|
"Destek üst Z mesafesi 0 ise bu değer yok sayılır ve nesne "
|
||||||
|
"sal ile doğrudan temas halinde basılır (boşluk yok)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Raft genişletme"
|
msgstr "Raft genişletme"
|
||||||
@@ -15274,14 +15280,20 @@ msgstr "Muhtemelen destek gerektirmeyen küçük çıkıntıları göz ardı edi
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Üst z mesafesi"
|
msgstr "Üst z mesafesi"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Üst destek arayüzü ile nesne arasındaki z boşluğu."
|
msgstr "Desteğin üstü ile nesne arasındaki Z boşluğu."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Alt z mesafesi"
|
msgstr "Alt z mesafesi"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Alt destek arayüzü ile nesne arasındaki z boşluğu."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Nesne ile destek altı arasındaki Z boşluğu. "
|
||||||
|
"Destek üst Z mesafesi 0 ise ve altta arayüz katmanları varsa bu değer yok "
|
||||||
|
"sayılır ve destek nesneyle doğrudan temas halinde basılır (boşluk yok)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Destek/raft tabanı"
|
msgstr "Destek/raft tabanı"
|
||||||
|
|||||||
@@ -15868,9 +15868,14 @@ msgstr "Варіант принтера"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Відстань Z контакту підкладки"
|
msgstr "Відстань Z контакту підкладки"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Зазор Z між об'єктом та підкладкою. Ігнорується для розчинного інтерфейсу"
|
"Z-зазор між підкладкою та моделлю. "
|
||||||
|
"Якщо верхній Z-зазор підтримки дорівнює 0, це значення ігнорується, "
|
||||||
|
"і модель друкується в прямому контакті з підкладкою (без зазору)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Розширення підкладки"
|
msgstr "Розширення підкладки"
|
||||||
@@ -16823,14 +16828,20 @@ msgstr ""
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Верхня відстань Z"
|
msgstr "Верхня відстань Z"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Зазор осі z між верхом підтримки та об'єктом"
|
msgstr "Z-зазор між верхом підтримки та моделлю."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Нижня відстань Z"
|
msgstr "Нижня відстань Z"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Зазор осі z між низом підтримки та об'єктом"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Z-зазор між моделлю та нижньою частиною підтримки. "
|
||||||
|
"Якщо верхній Z-зазор підтримки дорівнює 0 і знизу є інтерфейсні шари, це значення "
|
||||||
|
"ігнорується, і підтримка друкується в прямому контакті з моделлю (без зазору)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "База підтримки/підкладки"
|
msgstr "База підтримки/підкладки"
|
||||||
|
|||||||
@@ -16082,8 +16082,14 @@ msgstr "Biến thể máy in"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "Khoảng cách Z tiếp xúc raft"
|
msgstr "Khoảng cách Z tiếp xúc raft"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "Khe Z giữa đối tượng và raft. Bị bỏ qua cho giao diện hòa tan."
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Khoảng cách Z giữa bè và vật thể. "
|
||||||
|
"Nếu khoảng cách Z trên của hỗ trợ bằng 0, giá trị này sẽ bị bỏ qua "
|
||||||
|
"và vật thể được in tiếp xúc trực tiếp với bè (không có khe hở)."
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "Mở rộng raft"
|
msgstr "Mở rộng raft"
|
||||||
@@ -17024,14 +17030,20 @@ msgstr "Ignore small overhangs that possibly don't require support."
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "Khoảng cách Z trên"
|
msgstr "Khoảng cách Z trên"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "Khe Z giữa giao diện support trên và đối tượng."
|
msgstr "Khoảng cách Z giữa mặt trên của hỗ trợ và vật thể."
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "Khoảng cách Z dưới"
|
msgstr "Khoảng cách Z dưới"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "Khe Z giữa giao diện support dưới và đối tượng."
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"Khoảng cách Z giữa vật thể và phần đáy của hỗ trợ. "
|
||||||
|
"Nếu khoảng cách Z trên của hỗ trợ bằng 0 và phần đáy có các lớp giao diện, giá trị "
|
||||||
|
"này sẽ bị bỏ qua và hỗ trợ được in tiếp xúc trực tiếp với vật thể (không có khe hở)."
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "Đế support/raft"
|
msgstr "Đế support/raft"
|
||||||
@@ -22875,3 +22887,4 @@ msgstr ""
|
|||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid "*Printing %s material with %s may cause nozzle damage"
|
#~ msgid "*Printing %s material with %s may cause nozzle damage"
|
||||||
#~ msgstr "*In vật liệu %s với %s có thể gây hư hỏng đầu phun"
|
#~ msgstr "*In vật liệu %s với %s có thể gây hư hỏng đầu phun"
|
||||||
|
|
||||||
|
|||||||
@@ -15131,8 +15131,11 @@ msgstr "打印机变种"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "筏层Z间距"
|
msgstr "筏层Z间距"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "模型和筏层之间的Z间隙"
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr "筏层与模型之间的Z间隙。如果支撑顶部Z距离为0,则忽略该值,模型与筏层直接接触打印(无间隙)。"
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "筏层扩展"
|
msgstr "筏层扩展"
|
||||||
@@ -15991,14 +15994,19 @@ msgstr "将几乎不需要支撑的微小悬垂忽略掉。"
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "顶部Z距离"
|
msgstr "顶部Z距离"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "支撑顶部和模型之间的z间隙"
|
msgstr "支撑顶部与模型之间的Z间隙。"
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "底部Z距离"
|
msgstr "底部Z距离"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "支撑生成于模型表面时,支撑面底部和模型之间的z间隙"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"模型与支撑底部之间的Z间隙。"
|
||||||
|
"如果支撑顶部Z距离为0且底部有界面层,则忽略该值,支撑与模型直接接触打印(无间隙)。"
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "支撑/筏层主体"
|
msgstr "支撑/筏层主体"
|
||||||
|
|||||||
@@ -4152,7 +4152,7 @@ msgstr ""
|
|||||||
"重設為 0。seam_slope_start_height 必須小於 layer_height。\n"
|
"重設為 0。seam_slope_start_height 必須小於 layer_height。\n"
|
||||||
"重設為 0。"
|
"重設為 0。"
|
||||||
|
|
||||||
#, no-c-format, no-boost-format
|
#, fuzzy, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Lock depth should smaller than skin depth.\n"
|
"Lock depth should smaller than skin depth.\n"
|
||||||
"Reset to 50% of skin depth."
|
"Reset to 50% of skin depth."
|
||||||
@@ -15263,8 +15263,11 @@ msgstr "列印設備型號"
|
|||||||
msgid "Raft contact Z distance"
|
msgid "Raft contact Z distance"
|
||||||
msgstr "筏層 Z 間距"
|
msgstr "筏層 Z 間距"
|
||||||
|
|
||||||
msgid "Z gap between object and raft. Ignored for soluble interface."
|
msgid ""
|
||||||
msgstr "模型和筏層之間的Z間隙"
|
"Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap)."
|
||||||
|
msgstr "筏層與模型之間的Z間隙。若支撐頂部Z距離為0,則忽略此值,模型與筏層直接接觸列印(無間隙)。"
|
||||||
|
|
||||||
msgid "Raft expansion"
|
msgid "Raft expansion"
|
||||||
msgstr "筏層擴展"
|
msgstr "筏層擴展"
|
||||||
@@ -16127,14 +16130,19 @@ msgstr "將幾乎不需要支撐的微小懸空忽略掉。"
|
|||||||
msgid "Top Z distance"
|
msgid "Top Z distance"
|
||||||
msgstr "頂部 Z 間距"
|
msgstr "頂部 Z 間距"
|
||||||
|
|
||||||
msgid "The Z gap between the top support interface and object."
|
msgid "Z gap between the support's top and object."
|
||||||
msgstr "支撐頂部和模型之間的 Z 間隙"
|
msgstr "支撐頂部與模型之間的Z間隙。"
|
||||||
|
|
||||||
msgid "Bottom Z distance"
|
msgid "Bottom Z distance"
|
||||||
msgstr "底部 Z 間距"
|
msgstr "底部 Z 間距"
|
||||||
|
|
||||||
msgid "The Z gap between the bottom support interface and object."
|
msgid ""
|
||||||
msgstr "支撐產生於模型表面時,支撐面底部和模型之間的 Z 間隙"
|
"Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap)."
|
||||||
|
msgstr ""
|
||||||
|
"模型與支撐底部之間的Z間隙。"
|
||||||
|
"若支撐頂部Z距離為0且底部有介面層,則忽略此值,支撐與模型直接接觸列印(無間隙)。"
|
||||||
|
|
||||||
msgid "Support/raft base"
|
msgid "Support/raft base"
|
||||||
msgstr "支撐/筏層主體"
|
msgstr "支撐/筏層主體"
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ protected:
|
|||||||
ExPolygon *area;
|
ExPolygon *area;
|
||||||
int type;
|
int type;
|
||||||
int interface_id = 0;
|
int interface_id = 0;
|
||||||
|
bool interface_as_base = false;
|
||||||
coordf_t dist_to_top; // mm dist to top
|
coordf_t dist_to_top; // mm dist to top
|
||||||
bool need_infill = false;
|
bool need_infill = false;
|
||||||
bool need_extra_wall = false;
|
bool need_extra_wall = false;
|
||||||
|
|||||||
@@ -4854,7 +4854,9 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def = this->add("raft_contact_distance", coFloat);
|
def = this->add("raft_contact_distance", coFloat);
|
||||||
def->label = L("Raft contact Z distance");
|
def->label = L("Raft contact Z distance");
|
||||||
def->category = L("Support");
|
def->category = L("Support");
|
||||||
def->tooltip = L("Z gap between object and raft. Ignored for soluble interface.");
|
def->tooltip = L("Z gap between raft and object. "
|
||||||
|
"If Support Top Z Distance is 0, this value is ignored and "
|
||||||
|
"the object is printed in direct contact with the raft (no gap).");
|
||||||
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
@@ -5839,7 +5841,7 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->label = L("Top Z distance");
|
def->label = L("Top Z distance");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->category = L("Support");
|
def->category = L("Support");
|
||||||
def->tooltip = L("The Z gap between the top support interface and object.");
|
def->tooltip = L("Z gap between the support's top and object.");
|
||||||
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
||||||
// def->min = 0;
|
// def->min = 0;
|
||||||
#if 0
|
#if 0
|
||||||
@@ -5856,7 +5858,9 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def = this->add("support_bottom_z_distance", coFloat);
|
def = this->add("support_bottom_z_distance", coFloat);
|
||||||
def->label = L("Bottom Z distance");
|
def->label = L("Bottom Z distance");
|
||||||
def->category = L("Support");
|
def->category = L("Support");
|
||||||
def->tooltip = L("The Z gap between the bottom support interface and object.");
|
def->tooltip = L("Z gap between the object and the support bottom. "
|
||||||
|
"If Support Top Z Distance is 0 and the bottom has interface layers, this value "
|
||||||
|
"is ignored and the support is printed in direct contact with the object (no gap).");
|
||||||
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
|
|||||||
+76
-11
@@ -68,6 +68,7 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||||||
{
|
{
|
||||||
coordf_t initial_layer_print_height = (print_config.initial_layer_print_height.value <= 0) ?
|
coordf_t initial_layer_print_height = (print_config.initial_layer_print_height.value <= 0) ?
|
||||||
object_config.layer_height.value : print_config.initial_layer_print_height.value;
|
object_config.layer_height.value : print_config.initial_layer_print_height.value;
|
||||||
|
|
||||||
// If object_config.support_filament == 0 resp. object_config.support_interface_filament == 0,
|
// If object_config.support_filament == 0 resp. object_config.support_interface_filament == 0,
|
||||||
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
// print_config.nozzle_diameter.get_at(size_t(-1)) returns the 0th nozzle diameter,
|
||||||
// which is consistent with the requirement that if support_filament == 0 resp. support_interface_filament == 0,
|
// which is consistent with the requirement that if support_filament == 0 resp. support_interface_filament == 0,
|
||||||
@@ -75,19 +76,47 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||||||
// In that case all the nozzles have to be of the same diameter.
|
// In that case all the nozzles have to be of the same diameter.
|
||||||
coordf_t support_material_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_filament.value - 1);
|
coordf_t support_material_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_filament.value - 1);
|
||||||
coordf_t support_material_interface_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_interface_filament.value - 1);
|
coordf_t support_material_interface_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_interface_filament.value - 1);
|
||||||
bool soluble_interface = object_config.support_top_z_distance.value == 0.;
|
|
||||||
|
// ORCA: store Z distance
|
||||||
|
const coordf_t support_top_z_gap = object_config.support_top_z_distance.value;
|
||||||
|
const coordf_t support_bottom_z_gap = object_config.support_bottom_z_distance.value;
|
||||||
|
const coordf_t raft_z_gap = object_config.raft_contact_distance.value;
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* ORCA: Zero-gap interface detection (asymmetric) */
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
|
const bool zero_topZ_contact =
|
||||||
|
support_top_z_gap == 0.0;
|
||||||
|
|
||||||
|
const bool zero_gap_interface_top =
|
||||||
|
object_config.support_interface_top_layers.value > 0 && // Has some top interface layers
|
||||||
|
zero_topZ_contact;
|
||||||
|
|
||||||
|
const bool zero_gap_interface_bottom =
|
||||||
|
(object_config.support_interface_bottom_layers.value < 0 // Negative value means "use same as top"
|
||||||
|
? object_config.support_interface_top_layers.value
|
||||||
|
: object_config.support_interface_bottom_layers.value) > 0 && // Has some bottom interface layers
|
||||||
|
(support_bottom_z_gap == 0.0 || zero_topZ_contact);
|
||||||
|
|
||||||
|
const bool zero_gap_interface_raft =
|
||||||
|
raft_z_gap == 0.0 || zero_topZ_contact;
|
||||||
|
|
||||||
SlicingParameters params;
|
SlicingParameters params;
|
||||||
|
|
||||||
params.layer_height = object_config.layer_height.value;
|
params.layer_height = object_config.layer_height.value;
|
||||||
params.first_print_layer_height = initial_layer_print_height;
|
params.first_print_layer_height = initial_layer_print_height;
|
||||||
params.first_object_layer_height = initial_layer_print_height;
|
params.first_object_layer_height = initial_layer_print_height;
|
||||||
params.object_print_z_min = 0.;
|
params.object_print_z_min = 0.0;
|
||||||
// Orca: XYZ filament compensation
|
// Orca: XYZ filament compensation
|
||||||
params.object_print_z_max = object_height * object_shrinkage_compensation.z();
|
params.object_print_z_max = object_height * object_shrinkage_compensation.z();
|
||||||
params.object_print_z_uncompensated_max = object_height;
|
params.object_print_z_uncompensated_max = object_height;
|
||||||
params.object_shrinkage_compensation_z = object_shrinkage_compensation.z();
|
params.object_shrinkage_compensation_z = object_shrinkage_compensation.z();
|
||||||
params.base_raft_layers = object_config.raft_layers.value;
|
params.base_raft_layers = object_config.raft_layers.value;
|
||||||
params.soluble_interface = soluble_interface;
|
params.zero_gap_interface_top = zero_gap_interface_top;
|
||||||
|
params.zero_gap_interface_bottom = zero_gap_interface_bottom;
|
||||||
|
params.zero_gap_interface_raft = zero_gap_interface_raft;
|
||||||
|
|
||||||
// Miniumum/maximum of the minimum layer height over all extruders.
|
// Miniumum/maximum of the minimum layer height over all extruders.
|
||||||
params.min_layer_height = MIN_LAYER_HEIGHT;
|
params.min_layer_height = MIN_LAYER_HEIGHT;
|
||||||
@@ -102,6 +131,7 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||||||
max_layer_height_from_nozzle(print_config, object_config.support_interface_filament));
|
max_layer_height_from_nozzle(print_config, object_config.support_interface_filament));
|
||||||
params.max_suport_layer_height = params.max_layer_height;
|
params.max_suport_layer_height = params.max_layer_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object_extruders.empty()) {
|
if (object_extruders.empty()) {
|
||||||
params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, 0));
|
params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, 0));
|
||||||
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, 0));
|
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, 0));
|
||||||
@@ -111,22 +141,56 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||||||
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, extruder_id));
|
params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, extruder_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
params.min_layer_height = std::min(params.min_layer_height, params.layer_height);
|
params.min_layer_height = std::min(params.min_layer_height, params.layer_height);
|
||||||
params.max_layer_height = std::max(params.max_layer_height, params.layer_height);
|
params.max_layer_height = std::max(params.max_layer_height, params.layer_height);
|
||||||
|
|
||||||
if (! soluble_interface) {
|
/* -------------------------------------------------- */
|
||||||
params.gap_raft_object = object_config.raft_contact_distance.value;
|
/* ORCA: Gap assignment */
|
||||||
//BBS
|
/* -------------------------------------------------- */
|
||||||
params.gap_object_support = object_config.support_bottom_z_distance.value;
|
|
||||||
params.gap_support_object = object_config.support_top_z_distance.value;
|
// ORCA: Raft contact (raft -> object)
|
||||||
|
if (zero_gap_interface_raft) {
|
||||||
|
params.gap_raft_object = 0.0;
|
||||||
|
} else {
|
||||||
|
params.gap_raft_object = raft_z_gap;
|
||||||
|
if (!print_config.independent_support_layer_height) {
|
||||||
|
params.gap_raft_object =
|
||||||
|
std::round(params.gap_raft_object / object_config.layer_height + EPSILON)
|
||||||
|
* object_config.layer_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORCA: BOTTOM contact (object -> support)
|
||||||
|
if (zero_gap_interface_bottom) {
|
||||||
|
params.gap_object_support = 0.0;
|
||||||
|
} else {
|
||||||
|
params.gap_object_support = support_bottom_z_gap;
|
||||||
|
|
||||||
if (!print_config.independent_support_layer_height) {
|
if (!print_config.independent_support_layer_height) {
|
||||||
params.gap_raft_object = std::round(params.gap_raft_object / object_config.layer_height + EPSILON) * object_config.layer_height;
|
params.gap_object_support =
|
||||||
params.gap_object_support = std::round(params.gap_object_support / object_config.layer_height + EPSILON) * object_config.layer_height;
|
std::round(params.gap_object_support / object_config.layer_height + EPSILON)
|
||||||
params.gap_support_object = std::round(params.gap_support_object / object_config.layer_height + EPSILON) * object_config.layer_height;
|
* object_config.layer_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ORCA: TOP contact (support -> object)
|
||||||
|
if (zero_gap_interface_top) {
|
||||||
|
params.gap_support_object = 0.0;
|
||||||
|
} else {
|
||||||
|
params.gap_support_object = support_top_z_gap;
|
||||||
|
|
||||||
|
if (!print_config.independent_support_layer_height) {
|
||||||
|
params.gap_support_object =
|
||||||
|
std::round(params.gap_support_object / object_config.layer_height + EPSILON)
|
||||||
|
* object_config.layer_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* Raft logic */
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
|
||||||
if (params.base_raft_layers > 0) {
|
if (params.base_raft_layers > 0) {
|
||||||
params.interface_raft_layers = (params.base_raft_layers + 1) / 2;
|
params.interface_raft_layers = (params.base_raft_layers + 1) / 2;
|
||||||
params.base_raft_layers -= params.interface_raft_layers;
|
params.base_raft_layers -= params.interface_raft_layers;
|
||||||
@@ -154,6 +218,7 @@ SlicingParameters SlicingParameters::create_from_config(
|
|||||||
params.raft_interface_top_z = params.raft_base_top_z + coordf_t(params.interface_raft_layers - 1) * params.interface_raft_layer_height;
|
params.raft_interface_top_z = params.raft_base_top_z + coordf_t(params.interface_raft_layers - 1) * params.interface_raft_layer_height;
|
||||||
params.raft_contact_top_z = params.raft_interface_top_z + params.contact_raft_layer_height;
|
params.raft_contact_top_z = params.raft_interface_top_z + params.contact_raft_layer_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
coordf_t print_z = params.raft_contact_top_z + params.gap_raft_object;
|
coordf_t print_z = params.raft_contact_top_z + params.gap_raft_object;
|
||||||
params.object_print_z_min = print_z;
|
params.object_print_z_min = print_z;
|
||||||
params.object_print_z_max += print_z;
|
params.object_print_z_max += print_z;
|
||||||
|
|||||||
@@ -84,9 +84,10 @@ struct SlicingParameters
|
|||||||
// If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
|
// If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
|
||||||
bool first_object_layer_bridging { false };
|
bool first_object_layer_bridging { false };
|
||||||
|
|
||||||
// Soluble interface? (PLA soluble in water, HIPS soluble in lemonen)
|
// Zero-gap interface flags for top / bottom / raft contact.
|
||||||
// otherwise the interface must be broken off.
|
bool zero_gap_interface_top { false };
|
||||||
bool soluble_interface { false };
|
bool zero_gap_interface_bottom { false };
|
||||||
|
bool zero_gap_interface_raft { false };
|
||||||
// Gap when placing object over raft.
|
// Gap when placing object over raft.
|
||||||
coordf_t gap_raft_object { 0 };
|
coordf_t gap_raft_object { 0 };
|
||||||
// Gap when placing support over object.
|
// Gap when placing support over object.
|
||||||
@@ -100,7 +101,7 @@ struct SlicingParameters
|
|||||||
coordf_t raft_base_top_z { 0 };
|
coordf_t raft_base_top_z { 0 };
|
||||||
coordf_t raft_interface_top_z { 0 };
|
coordf_t raft_interface_top_z { 0 };
|
||||||
coordf_t raft_contact_top_z { 0 };
|
coordf_t raft_contact_top_z { 0 };
|
||||||
// In case of a soluble interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
|
// In case of a zero-gap raft interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
|
||||||
coordf_t object_print_z_min { 0 };
|
coordf_t object_print_z_min { 0 };
|
||||||
// This value of maximum print Z is scaled by shrinkage compensation in the Z-axis.
|
// This value of maximum print Z is scaled by shrinkage compensation in the Z-axis.
|
||||||
coordf_t object_print_z_max { 0 };
|
coordf_t object_print_z_max { 0 };
|
||||||
@@ -133,7 +134,9 @@ inline bool equal_layering(const SlicingParameters &sp1, const SlicingParameters
|
|||||||
// BBS: following are not required for equal layer height.
|
// BBS: following are not required for equal layer height.
|
||||||
// Since the z-gap diff may be multiple of layer height.
|
// Since the z-gap diff may be multiple of layer height.
|
||||||
#if 0
|
#if 0
|
||||||
sp1.soluble_interface == sp2.soluble_interface &&
|
sp1.zero_gap_interface_top == sp2.zero_gap_interface_top &&
|
||||||
|
sp1.zero_gap_interface_bottom == sp2.zero_gap_interface_bottom &&
|
||||||
|
sp1.zero_gap_interface_raft == sp2.zero_gap_interface_raft &&
|
||||||
sp1.gap_raft_object == sp2.gap_raft_object &&
|
sp1.gap_raft_object == sp2.gap_raft_object &&
|
||||||
sp1.gap_object_support == sp2.gap_object_support &&
|
sp1.gap_object_support == sp2.gap_object_support &&
|
||||||
sp1.gap_support_object == sp2.gap_support_object &&
|
sp1.gap_support_object == sp2.gap_support_object &&
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include "SupportCommon.hpp"
|
#include "SupportCommon.hpp"
|
||||||
@@ -69,22 +70,30 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
|
|||||||
if (support_params.has_base_interfaces())
|
if (support_params.has_base_interfaces())
|
||||||
base_interface_layers.assign(intermediate_layers.size(), nullptr);
|
base_interface_layers.assign(intermediate_layers.size(), nullptr);
|
||||||
const auto smoothing_distance = support_params.support_material_interface_flow.scaled_spacing() * 1.5;
|
const auto smoothing_distance = support_params.support_material_interface_flow.scaled_spacing() * 1.5;
|
||||||
const auto minimum_island_radius = support_params.support_material_interface_flow.scaled_spacing() / support_params.interface_density;
|
// ORCA: use top/bottom interface densities for smoothing.
|
||||||
|
const auto minimum_island_radius_top = support_params.support_material_interface_flow.scaled_spacing() / support_params.top_interface_density;
|
||||||
|
const auto minimum_island_radius_bottom = support_params.support_material_interface_flow.scaled_spacing() / support_params.bottom_interface_density;
|
||||||
const auto closing_distance = smoothing_distance; // scaled<float>(config.support_material_closing_radius.value);
|
const auto closing_distance = smoothing_distance; // scaled<float>(config.support_material_closing_radius.value);
|
||||||
// Insert a new layer into base_interface_layers, if intersection with base exists.
|
// Insert a new layer into base_interface_layers, if intersection with base exists.
|
||||||
auto insert_layer = [&layer_storage, smooth_supports, closing_distance, smoothing_distance, minimum_island_radius](
|
// ORCA: regularize top and bottom interfaces with separate minimum island radii.
|
||||||
|
auto insert_layer = [&layer_storage, smooth_supports, closing_distance, smoothing_distance, minimum_island_radius_top, minimum_island_radius_bottom](
|
||||||
SupportGeneratorLayer &intermediate_layer, Polygons &bottom, Polygons &&top, SupportGeneratorLayer *top_interface_layer,
|
SupportGeneratorLayer &intermediate_layer, Polygons &bottom, Polygons &&top, SupportGeneratorLayer *top_interface_layer,
|
||||||
const Polygons *subtract, SupporLayerType type) -> SupportGeneratorLayer* {
|
const Polygons *subtract, SupporLayerType type) -> SupportGeneratorLayer* {
|
||||||
bool has_top_interface = top_interface_layer && ! top_interface_layer->polygons.empty();
|
bool has_top_interface = top_interface_layer && ! top_interface_layer->polygons.empty();
|
||||||
assert(! bottom.empty() || ! top.empty() || has_top_interface);
|
assert(! bottom.empty() || ! top.empty() || has_top_interface);
|
||||||
// Merge top into bottom, unite them with a safety offset.
|
// ORCA: regularize interfaces using the top/bottom radii.
|
||||||
append(bottom, std::move(top));
|
auto regularize = [&](Polygons polys, coordf_t minimum_island_radius) -> Polygons {
|
||||||
// Merge top / bottom interfaces. For snug supports, merge using closing distance and regularize (close concave corners).
|
if (polys.empty())
|
||||||
bottom = intersection(
|
return polys;
|
||||||
smooth_supports ?
|
return smooth_supports ?
|
||||||
smooth_outward(closing(std::move(bottom), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
|
smooth_outward(closing(std::move(polys), closing_distance + minimum_island_radius, closing_distance, SUPPORT_SURFACES_OFFSET_PARAMETERS), smoothing_distance) :
|
||||||
union_safety_offset(std::move(bottom)),
|
union_safety_offset(std::move(polys));
|
||||||
intermediate_layer.polygons);
|
};
|
||||||
|
// ORCA: apply independent smoothing to bottom vs top.
|
||||||
|
Polygons bottom_polys = regularize(std::move(bottom), minimum_island_radius_bottom);
|
||||||
|
Polygons top_polys = regularize(std::move(top), minimum_island_radius_top);
|
||||||
|
append(bottom_polys, std::move(top_polys));
|
||||||
|
bottom = intersection(std::move(bottom_polys), intermediate_layer.polygons);
|
||||||
if (has_top_interface) {
|
if (has_top_interface) {
|
||||||
// Don't trim the precomputed Organic supports top interface with base layer
|
// Don't trim the precomputed Organic supports top interface with base layer
|
||||||
// as the precomputed top interface likely expands over multiple tree tips.
|
// as the precomputed top interface likely expands over multiple tree tips.
|
||||||
@@ -1365,7 +1374,8 @@ SupportGeneratorLayersPtr generate_support_layers(
|
|||||||
SupportGeneratorLayer &layer = *layers_sorted[u];
|
SupportGeneratorLayer &layer = *layers_sorted[u];
|
||||||
if (! layer.polygons.empty()) {
|
if (! layer.polygons.empty()) {
|
||||||
empty = false;
|
empty = false;
|
||||||
num_interfaces += one_of(layer.layer_type, support_types_interface);
|
const bool is_base_interface = std::find(base_interface_layers.begin(), base_interface_layers.end(), &layer) != base_interface_layers.end();
|
||||||
|
num_interfaces += one_of(layer.layer_type, support_types_interface) || is_base_interface;
|
||||||
if (layer.layer_type == SupporLayerType::TopContact) {
|
if (layer.layer_type == SupporLayerType::TopContact) {
|
||||||
++ num_top_contacts;
|
++ num_top_contacts;
|
||||||
assert(num_top_contacts <= 1);
|
assert(num_top_contacts <= 1);
|
||||||
@@ -1562,7 +1572,7 @@ void generate_support_toolpaths(
|
|||||||
auto filler_raft_contact = filler_raft_contact_ptr ? filler_raft_contact_ptr.get() : filler_interface.get();
|
auto filler_raft_contact = filler_raft_contact_ptr ? filler_raft_contact_ptr.get() : filler_interface.get();
|
||||||
// Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer).
|
// Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer).
|
||||||
auto filler_base_interface = std::unique_ptr<Fill>(base_interface_layers.empty() ? nullptr :
|
auto filler_base_interface = std::unique_ptr<Fill>(base_interface_layers.empty() ? nullptr :
|
||||||
Fill::new_from_type(support_params.interface_density > 0.95 || support_params.with_sheath ? ipRectilinear : ipSupportBase));
|
Fill::new_from_type(support_params.top_interface_density > 0.95 || support_params.with_sheath ? ipRectilinear : ipSupportBase));
|
||||||
auto filler_support = std::unique_ptr<Fill>(Fill::new_from_type(support_params.base_fill_pattern));
|
auto filler_support = std::unique_ptr<Fill>(Fill::new_from_type(support_params.base_fill_pattern));
|
||||||
filler_interface->set_bounding_box(bbox_object);
|
filler_interface->set_bounding_box(bbox_object);
|
||||||
if (filler_first_layer_ptr)
|
if (filler_first_layer_ptr)
|
||||||
@@ -1610,6 +1620,8 @@ void generate_support_toolpaths(
|
|||||||
|
|
||||||
// This layer is a raft contact layer. Any contact polygons at this layer are raft contacts.
|
// This layer is a raft contact layer. Any contact polygons at this layer are raft contacts.
|
||||||
bool raft_layer = slicing_params.interface_raft_layers && top_contact_layer.layer && is_approx(top_contact_layer.layer->print_z, slicing_params.raft_contact_top_z);
|
bool raft_layer = slicing_params.interface_raft_layers && top_contact_layer.layer && is_approx(top_contact_layer.layer->print_z, slicing_params.raft_contact_top_z);
|
||||||
|
// ORCA: Organic tree uses projected contacts to build the interface stack; avoid extra bottom-contact extrusion.
|
||||||
|
const bool organic_tree = support_params.support_style == SupportMaterialStyle::smsTreeOrganic;
|
||||||
if (config.support_interface_top_layers == 0) {
|
if (config.support_interface_top_layers == 0) {
|
||||||
// If no top interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
// If no top interface layers were requested, we treat the contact layer exactly as a generic base layer.
|
||||||
// Don't merge the raft contact layer though.
|
// Don't merge the raft contact layer though.
|
||||||
@@ -1638,10 +1650,34 @@ void generate_support_toolpaths(
|
|||||||
base_layer.merge(std::move(bottom_contact_layer));
|
base_layer.merge(std::move(bottom_contact_layer));
|
||||||
else if (base_layer.empty() && ! bottom_contact_layer.empty() && ! bottom_contact_layer.layer->bridging)
|
else if (base_layer.empty() && ! bottom_contact_layer.empty() && ! bottom_contact_layer.layer->bridging)
|
||||||
base_layer = std::move(bottom_contact_layer);
|
base_layer = std::move(bottom_contact_layer);
|
||||||
} else if (bottom_contact_layer.could_merge(top_contact_layer) && ! raft_layer)
|
} else if (bottom_contact_layer.could_merge(top_contact_layer) && ! raft_layer) {
|
||||||
top_contact_layer.merge(std::move(bottom_contact_layer));
|
top_contact_layer.merge(std::move(bottom_contact_layer));
|
||||||
else if (bottom_contact_layer.could_merge(interface_layer))
|
} else if (bottom_contact_layer.could_merge(interface_layer) && ! organic_tree) {
|
||||||
bottom_contact_layer.merge(std::move(interface_layer));
|
bottom_contact_layer.merge(std::move(interface_layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orca: For organic trees the support-material regions are generated from
|
||||||
|
// expanded wall polygons. With zero top Z gap and separate interface material,
|
||||||
|
// that expansion can overlap same-layer interface-material regions, so trim
|
||||||
|
// the support-material regions from those interface footprints here.
|
||||||
|
if (organic_tree && support_params.zero_gap_interface_top && !support_params.can_merge_support_regions &&
|
||||||
|
(!base_layer.empty() || !base_interface_layer.empty())) {
|
||||||
|
Polygons interface_polygons;
|
||||||
|
if (!top_contact_layer.empty())
|
||||||
|
polygons_append(interface_polygons, top_contact_layer.polygons_to_extrude());
|
||||||
|
if (!interface_layer.empty())
|
||||||
|
polygons_append(interface_polygons, interface_layer.polygons_to_extrude());
|
||||||
|
if (!interface_polygons.empty()) {
|
||||||
|
const coord_t trim_margin = std::max(
|
||||||
|
support_params.support_material_flow.scaled_width(),
|
||||||
|
support_params.support_material_interface_flow.scaled_width());
|
||||||
|
Polygons interface_keepout = offset(interface_polygons, trim_margin);
|
||||||
|
if (!base_layer.empty())
|
||||||
|
base_layer.set_polygons_to_extrude(diff(base_layer.polygons_to_extrude(), interface_keepout));
|
||||||
|
if (!base_interface_layer.empty())
|
||||||
|
base_interface_layer.set_polygons_to_extrude(diff(base_interface_layer.polygons_to_extrude(), interface_keepout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( ! interface_layer.empty() && ! base_layer.empty()) {
|
if ( ! interface_layer.empty() && ! base_layer.empty()) {
|
||||||
@@ -1661,6 +1697,9 @@ void generate_support_toolpaths(
|
|||||||
if (! layer_ex.empty() && ! layer_ex.polygons_to_extrude().empty()) {
|
if (! layer_ex.empty() && ! layer_ex.polygons_to_extrude().empty()) {
|
||||||
bool interface_as_base = interface_layer_type == InterfaceLayerType::InterfaceAsBase;
|
bool interface_as_base = interface_layer_type == InterfaceLayerType::InterfaceAsBase;
|
||||||
bool raft_contact = interface_layer_type == InterfaceLayerType::RaftContact;
|
bool raft_contact = interface_layer_type == InterfaceLayerType::RaftContact;
|
||||||
|
// ORCA: detect bottom interface layers for density selection.
|
||||||
|
bool bottom_interface = interface_layer_type == InterfaceLayerType::BottomContact ||
|
||||||
|
(interface_layer_type == InterfaceLayerType::Interface && layer_ex.layer->layer_type == SupporLayerType::BottomInterface);
|
||||||
//FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore
|
//FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore
|
||||||
// the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b)
|
// the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b)
|
||||||
auto *filler = raft_contact ? filler_raft_contact : filler_interface.get();
|
auto *filler = raft_contact ? filler_raft_contact : filler_interface.get();
|
||||||
@@ -1676,7 +1715,10 @@ void generate_support_toolpaths(
|
|||||||
raft_contact ?
|
raft_contact ?
|
||||||
support_params.raft_interface_angle(support_layer.interface_id()) :
|
support_params.raft_interface_angle(support_layer.interface_id()) :
|
||||||
support_interface_angle;
|
support_interface_angle;
|
||||||
double density = raft_contact ? support_params.raft_interface_density : interface_as_base ? support_params.support_density : support_params.interface_density;
|
// ORCA: pick density based on interface type.
|
||||||
|
double density = raft_contact ? support_params.raft_interface_density :
|
||||||
|
interface_as_base ? support_params.support_density :
|
||||||
|
bottom_interface ? support_params.bottom_interface_density : support_params.top_interface_density;
|
||||||
filler->spacing = raft_contact ? support_params.raft_interface_flow.spacing() :
|
filler->spacing = raft_contact ? support_params.raft_interface_flow.spacing() :
|
||||||
interface_as_base ? support_params.support_material_flow.spacing() : support_params.support_material_interface_flow.spacing();
|
interface_as_base ? support_params.support_material_flow.spacing() : support_params.support_material_interface_flow.spacing();
|
||||||
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
|
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density));
|
||||||
@@ -1694,9 +1736,9 @@ void generate_support_toolpaths(
|
|||||||
const bool top_interfaces = config.support_interface_top_layers.value != 0;
|
const bool top_interfaces = config.support_interface_top_layers.value != 0;
|
||||||
const bool bottom_interfaces = top_interfaces && config.support_interface_bottom_layers != 0;
|
const bool bottom_interfaces = top_interfaces && config.support_interface_bottom_layers != 0;
|
||||||
extrude_interface(top_contact_layer, raft_layer ? InterfaceLayerType::RaftContact : top_interfaces ? InterfaceLayerType::TopContact : InterfaceLayerType::InterfaceAsBase);
|
extrude_interface(top_contact_layer, raft_layer ? InterfaceLayerType::RaftContact : top_interfaces ? InterfaceLayerType::TopContact : InterfaceLayerType::InterfaceAsBase);
|
||||||
|
if (!organic_tree)
|
||||||
extrude_interface(bottom_contact_layer, bottom_interfaces ? InterfaceLayerType::BottomContact : InterfaceLayerType::InterfaceAsBase);
|
extrude_interface(bottom_contact_layer, bottom_interfaces ? InterfaceLayerType::BottomContact : InterfaceLayerType::InterfaceAsBase);
|
||||||
extrude_interface(interface_layer, top_interfaces ? InterfaceLayerType::Interface : InterfaceLayerType::InterfaceAsBase);
|
extrude_interface(interface_layer, top_interfaces ? InterfaceLayerType::Interface : InterfaceLayerType::InterfaceAsBase);
|
||||||
|
|
||||||
// Base interface layers under soluble interfaces
|
// Base interface layers under soluble interfaces
|
||||||
if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()) {
|
if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()) {
|
||||||
Fill *filler = filler_base_interface.get();
|
Fill *filler = filler_base_interface.get();
|
||||||
@@ -1706,7 +1748,7 @@ void generate_support_toolpaths(
|
|||||||
Flow interface_flow = support_params.support_material_flow.with_height(float(base_interface_layer.layer->height));
|
Flow interface_flow = support_params.support_material_flow.with_height(float(base_interface_layer.layer->height));
|
||||||
filler->angle = support_interface_angle;
|
filler->angle = support_interface_angle;
|
||||||
filler->spacing = support_params.support_material_interface_flow.spacing();
|
filler->spacing = support_params.support_material_interface_flow.spacing();
|
||||||
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_params.interface_density));
|
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_params.top_interface_density));
|
||||||
fill_expolygons_generate_paths(
|
fill_expolygons_generate_paths(
|
||||||
// Destination
|
// Destination
|
||||||
base_interface_layer.extrusions,
|
base_interface_layer.extrusions,
|
||||||
@@ -1714,7 +1756,7 @@ void generate_support_toolpaths(
|
|||||||
// Regions to fill
|
// Regions to fill
|
||||||
union_safety_offset_ex(base_interface_layer.polygons_to_extrude()),
|
union_safety_offset_ex(base_interface_layer.polygons_to_extrude()),
|
||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler, float(support_params.interface_density),
|
filler, float(support_params.top_interface_density),
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
ExtrusionRole::erSupportMaterial, interface_flow);
|
ExtrusionRole::erSupportMaterial, interface_flow);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1739,7 +1739,7 @@ static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_cont
|
|||||||
print_z = slicing_params.raft_contact_top_z;
|
print_z = slicing_params.raft_contact_top_z;
|
||||||
bottom_z = slicing_params.raft_interface_top_z;
|
bottom_z = slicing_params.raft_interface_top_z;
|
||||||
height = slicing_params.contact_raft_layer_height;
|
height = slicing_params.contact_raft_layer_height;
|
||||||
} else if (slicing_params.soluble_interface) {
|
} else if (slicing_params.zero_gap_interface_top) {
|
||||||
// Align the contact surface height with a layer immediately below the supported layer.
|
// Align the contact surface height with a layer immediately below the supported layer.
|
||||||
// Interface layer will be synchronized with the object.
|
// Interface layer will be synchronized with the object.
|
||||||
print_z = layer.bottom_z();
|
print_z = layer.bottom_z();
|
||||||
@@ -1862,7 +1862,7 @@ static inline void fill_contact_layer(
|
|||||||
#endif // SLIC3R_DEBUG
|
#endif // SLIC3R_DEBUG
|
||||||
));
|
));
|
||||||
// 2) infill polygons, expand them by half the extrusion width + a tiny bit of extra.
|
// 2) infill polygons, expand them by half the extrusion width + a tiny bit of extra.
|
||||||
bool reduce_interfaces = object_config.support_style.value != smsSnug && layer_id > 0 && !slicing_params.soluble_interface;
|
bool reduce_interfaces = object_config.support_style.value != smsSnug && layer_id > 0 && !slicing_params.zero_gap_interface_top;
|
||||||
if (reduce_interfaces) {
|
if (reduce_interfaces) {
|
||||||
// Reduce the amount of dense interfaces: Do not generate dense interfaces below overhangs with 60% overhang of the extrusions.
|
// Reduce the amount of dense interfaces: Do not generate dense interfaces below overhangs with 60% overhang of the extrusions.
|
||||||
Polygons dense_interface_polygons = diff(overhang_polygons, lower_layer_polygons_for_dense_interface());
|
Polygons dense_interface_polygons = diff(overhang_polygons, lower_layer_polygons_for_dense_interface());
|
||||||
@@ -2421,12 +2421,12 @@ static inline SupportGeneratorLayer* detect_bottom_contacts(
|
|||||||
Layer* upper_layer = layer.upper_layer;
|
Layer* upper_layer = layer.upper_layer;
|
||||||
if (object.print()->config().independent_support_layer_height) {
|
if (object.print()->config().independent_support_layer_height) {
|
||||||
// If the layer is extruded with no bridging flow, support just the normal extrusions.
|
// If the layer is extruded with no bridging flow, support just the normal extrusions.
|
||||||
layer_new.height = slicing_params.soluble_interface ?
|
layer_new.height = slicing_params.zero_gap_interface_bottom ?
|
||||||
// Align the interface layer with the object's layer height.
|
// Align the interface layer with the object's layer height.
|
||||||
upper_layer->height :
|
upper_layer->height :
|
||||||
// Place a bridge flow interface layer or the normal flow interface layer over the top surface.
|
// Place a bridge flow interface layer or the normal flow interface layer over the top surface.
|
||||||
support_params.support_material_bottom_interface_flow.height();
|
support_params.support_material_bottom_interface_flow.height();
|
||||||
layer_new.print_z = slicing_params.soluble_interface ? upper_layer->print_z :
|
layer_new.print_z = slicing_params.zero_gap_interface_bottom ? upper_layer->print_z :
|
||||||
layer.print_z + layer_new.height + slicing_params.gap_object_support;
|
layer.print_z + layer_new.height + slicing_params.gap_object_support;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2436,11 +2436,11 @@ static inline SupportGeneratorLayer* detect_bottom_contacts(
|
|||||||
}
|
}
|
||||||
layer_new.bottom_z = layer.print_z;
|
layer_new.bottom_z = layer.print_z;
|
||||||
layer_new.idx_object_layer_below = layer_id;
|
layer_new.idx_object_layer_below = layer_id;
|
||||||
layer_new.bridging = !slicing_params.soluble_interface && object.config().thick_bridges;
|
layer_new.bridging = !slicing_params.zero_gap_interface_bottom && object.config().thick_bridges;
|
||||||
//FIXME how much to inflate the bottom surface, as it is being extruded with a bridging flow? The following line uses a normal flow.
|
//FIXME how much to inflate the bottom surface, as it is being extruded with a bridging flow? The following line uses a normal flow.
|
||||||
layer_new.polygons = expand(touching, float(support_params.support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
layer_new.polygons = expand(touching, float(support_params.support_material_flow.scaled_width()), SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||||
|
|
||||||
if (! slicing_params.soluble_interface) {
|
if (!slicing_params.zero_gap_interface_bottom) {
|
||||||
// Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface,
|
// Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface,
|
||||||
// so there will be no support surfaces generated with thickness lower than m_support_layer_height_min.
|
// so there will be no support surfaces generated with thickness lower than m_support_layer_height_min.
|
||||||
for (size_t top_idx = size_t(std::max<int>(0, contact_idx));
|
for (size_t top_idx = size_t(std::max<int>(0, contact_idx));
|
||||||
@@ -2909,7 +2909,7 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp
|
|||||||
// Continue printing the other layers up to extr2z.
|
// Continue printing the other layers up to extr2z.
|
||||||
step = dist / coordf_t(n_layers_extra);
|
step = dist / coordf_t(n_layers_extra);
|
||||||
}
|
}
|
||||||
if (! m_slicing_params.soluble_interface && extr2->layer_type == SupporLayerType::TopContact) {
|
if (!m_slicing_params.zero_gap_interface_top && extr2->layer_type == SupporLayerType::TopContact) {
|
||||||
// This is a top interface layer, which does not have a height assigned yet. Do it now.
|
// This is a top interface layer, which does not have a height assigned yet. Do it now.
|
||||||
assert(extr2->height == 0.);
|
assert(extr2->height == 0.);
|
||||||
assert(extr1z > m_slicing_params.first_print_layer_height - EPSILON);
|
assert(extr1z > m_slicing_params.first_print_layer_height - EPSILON);
|
||||||
@@ -3170,7 +3170,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
|
|||||||
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
|
if (!m_slicing_params.zero_gap_interface_top && m_object_config->thick_bridges) {
|
||||||
// Collect all bottom surfaces, which will be extruded with a bridging flow.
|
// Collect all bottom surfaces, which will be extruded with a bridging flow.
|
||||||
for (; i < object.layers().size(); ++ i) {
|
for (; i < object.layers().size(); ++ i) {
|
||||||
const Layer &object_layer = *object.layers()[i];
|
const Layer &object_layer = *object.layers()[i];
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public:
|
|||||||
bool has_support() const { return m_object_config->enable_support.value || m_object_config->enforce_support_layers; }
|
bool has_support() const { return m_object_config->enable_support.value || m_object_config->enforce_support_layers; }
|
||||||
bool build_plate_only() const { return this->has_support() && m_object_config->support_on_build_plate_only.value; }
|
bool build_plate_only() const { return this->has_support() && m_object_config->support_on_build_plate_only.value; }
|
||||||
// BBS
|
// BBS
|
||||||
bool synchronize_layers() const { return /*m_slicing_params.soluble_interface && */!m_print_config->independent_support_layer_height.value; }
|
bool synchronize_layers() const { return /*m_slicing_params.zero_gap_interface_top && */!m_print_config->independent_support_layer_height.value; }
|
||||||
bool has_contact_loops() const { return m_object_config->support_interface_loop_pattern.value; }
|
bool has_contact_loops() const { return m_object_config->support_interface_loop_pattern.value; }
|
||||||
|
|
||||||
// Generate support material for the object.
|
// Generate support material for the object.
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ struct SupportParameters {
|
|||||||
const PrintObjectConfig& object_config = object.config();
|
const PrintObjectConfig& object_config = object.config();
|
||||||
const SlicingParameters& slicing_params = object.slicing_parameters();
|
const SlicingParameters& slicing_params = object.slicing_parameters();
|
||||||
|
|
||||||
this->soluble_interface = slicing_params.soluble_interface;
|
this->zero_gap_interface_top = slicing_params.zero_gap_interface_top;
|
||||||
this->soluble_interface_non_soluble_base =
|
this->zero_gap_interface_bottom = slicing_params.zero_gap_interface_bottom;
|
||||||
// Zero z-gap between the overhangs and the support interface.
|
const bool soluble_interface_non_soluble_base =
|
||||||
slicing_params.soluble_interface &&
|
|
||||||
// Interface extruder soluble.
|
// Interface extruder soluble.
|
||||||
object_config.support_interface_filament.value > 0 && print_config.filament_soluble.get_at(object_config.support_interface_filament.value - 1) &&
|
object_config.support_interface_filament.value > 0 && print_config.filament_soluble.get_at(object_config.support_interface_filament.value - 1) &&
|
||||||
// Base extruder: Either "print with active extruder" not soluble.
|
// Base extruder: Either "print with active extruder" not soluble.
|
||||||
(object_config.support_filament.value == 0 || ! print_config.filament_soluble.get_at(object_config.support_filament.value - 1));
|
(object_config.support_filament.value == 0 || ! print_config.filament_soluble.get_at(object_config.support_filament.value - 1));
|
||||||
|
const bool non_soluble_base_top = this->zero_gap_interface_top && soluble_interface_non_soluble_base;
|
||||||
|
const bool non_soluble_base_bottom = this->zero_gap_interface_bottom && soluble_interface_non_soluble_base;
|
||||||
|
|
||||||
{
|
{
|
||||||
this->num_top_interface_layers = std::max(0, object_config.support_interface_top_layers.value);
|
this->num_top_interface_layers = std::max(0, object_config.support_interface_top_layers.value);
|
||||||
@@ -29,18 +30,24 @@ struct SupportParameters {
|
|||||||
num_top_interface_layers : object_config.support_interface_bottom_layers;
|
num_top_interface_layers : object_config.support_interface_bottom_layers;
|
||||||
this->has_top_contacts = num_top_interface_layers > 0;
|
this->has_top_contacts = num_top_interface_layers > 0;
|
||||||
this->has_bottom_contacts = num_bottom_interface_layers > 0;
|
this->has_bottom_contacts = num_bottom_interface_layers > 0;
|
||||||
if (this->soluble_interface_non_soluble_base) {
|
|
||||||
// Try to support soluble dense interfaces with non-soluble dense interfaces.
|
|
||||||
this->num_top_base_interface_layers = size_t(std::min(int(num_top_interface_layers) / 2, 2));
|
|
||||||
this->num_bottom_base_interface_layers = size_t(std::min(int(num_bottom_interface_layers) / 2, 2));
|
|
||||||
} else {
|
|
||||||
// BBS: if support interface and support base do not use the same filament, add a base layer to improve their adhesion
|
// BBS: if support interface and support base do not use the same filament, add a base layer to improve their adhesion
|
||||||
// Note: support materials (such as Supp.W) can't be used as support base now, so support interface and base are still using different filaments even if
|
// Note: support materials (such as Supp.W) can't be used as support base now, so support interface and base are still using different filaments even if
|
||||||
// support_filament==0
|
// support_filament==0
|
||||||
bool differnt_support_interface_filament = object_config.support_interface_filament != 0 &&
|
bool different_support_interface_filament = object_config.support_interface_filament != 0 &&
|
||||||
object_config.support_interface_filament != object_config.support_filament;
|
object_config.support_interface_filament != object_config.support_filament;
|
||||||
this->num_top_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
|
|
||||||
this->num_bottom_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
|
if (non_soluble_base_top) { // ORCA: Try to support soluble dense interfaces with non-soluble dense interfaces.
|
||||||
|
this->num_top_base_interface_layers = size_t(std::min(int(num_top_interface_layers) / 2, 2));
|
||||||
|
} else {
|
||||||
|
this->num_top_base_interface_layers =
|
||||||
|
(different_support_interface_filament && this->zero_gap_interface_top) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (non_soluble_base_bottom) { // ORCA: Try to support soluble dense interfaces with non-soluble dense interfaces.
|
||||||
|
this->num_bottom_base_interface_layers = size_t(std::min(int(num_bottom_interface_layers) / 2, 2));
|
||||||
|
} else {
|
||||||
|
this->num_bottom_base_interface_layers =
|
||||||
|
(different_support_interface_filament && this->zero_gap_interface_bottom) ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->first_layer_flow = Slic3r::support_material_1st_layer_flow(&object, float(slicing_params.first_print_layer_height));
|
this->first_layer_flow = Slic3r::support_material_1st_layer_flow(&object, float(slicing_params.first_print_layer_height));
|
||||||
@@ -78,7 +85,7 @@ struct SupportParameters {
|
|||||||
this->gap_xy_first_layer = object_config.support_object_first_layer_gap.value;
|
this->gap_xy_first_layer = object_config.support_object_first_layer_gap.value;
|
||||||
bridge_flow_ratio /= object.num_printing_regions();
|
bridge_flow_ratio /= object.num_printing_regions();
|
||||||
|
|
||||||
this->support_material_bottom_interface_flow = slicing_params.soluble_interface || !object_config.thick_bridges ?
|
this->support_material_bottom_interface_flow = this->zero_gap_interface_bottom || !object_config.thick_bridges ?
|
||||||
this->support_material_interface_flow.with_flow_ratio(bridge_flow_ratio) :
|
this->support_material_interface_flow.with_flow_ratio(bridge_flow_ratio) :
|
||||||
Flow::bridging_flow(bridge_flow_ratio * this->support_material_interface_flow.nozzle_diameter(), this->support_material_interface_flow.nozzle_diameter());
|
Flow::bridging_flow(bridge_flow_ratio * this->support_material_interface_flow.nozzle_diameter(), this->support_material_interface_flow.nozzle_diameter());
|
||||||
|
|
||||||
@@ -95,18 +102,21 @@ struct SupportParameters {
|
|||||||
|
|
||||||
this->base_angle = Geometry::deg2rad(float(object_config.support_angle.value));
|
this->base_angle = Geometry::deg2rad(float(object_config.support_angle.value));
|
||||||
this->interface_angle = Geometry::deg2rad(float(object_config.support_angle.value + 90.));
|
this->interface_angle = Geometry::deg2rad(float(object_config.support_angle.value + 90.));
|
||||||
// Orca: Force solid support interface when using support ironing
|
// ORCA: split top/bottom interface spacing and density, and force solid top when ironing.
|
||||||
this->interface_spacing = (this->ironing ? 0 : object_config.support_interface_spacing.value) + this->support_material_interface_flow.spacing();
|
this->top_interface_spacing = (this->ironing ? 0 : object_config.support_interface_spacing.value) + this->support_material_interface_flow.spacing();
|
||||||
this->interface_density = std::min(1., this->support_material_interface_flow.spacing() / this->interface_spacing);
|
this->top_interface_density = std::min(1., this->support_material_interface_flow.spacing() / this->top_interface_spacing);
|
||||||
// Orca: Force solid support interface when using support ironing
|
// ORCA: bottom interface spacing/density separated from top settings.
|
||||||
|
this->bottom_interface_spacing = object_config.support_bottom_interface_spacing.value + this->support_material_interface_flow.spacing();
|
||||||
|
this->bottom_interface_density = std::min(1., this->support_material_interface_flow.spacing() / this->bottom_interface_spacing);
|
||||||
|
// ORCA: force solid raft interface when ironing (top spacing).
|
||||||
double raft_interface_spacing = (this->ironing ? 0 : object_config.support_interface_spacing.value) + this->raft_interface_flow.spacing();
|
double raft_interface_spacing = (this->ironing ? 0 : object_config.support_interface_spacing.value) + this->raft_interface_flow.spacing();
|
||||||
this->raft_interface_density = std::min(1., this->raft_interface_flow.spacing() / raft_interface_spacing);
|
this->raft_interface_density = std::min(1., this->raft_interface_flow.spacing() / raft_interface_spacing);
|
||||||
this->support_spacing = object_config.support_base_pattern_spacing.value + this->support_material_flow.spacing();
|
this->support_spacing = object_config.support_base_pattern_spacing.value + this->support_material_flow.spacing();
|
||||||
this->support_density = std::min(1., this->support_material_flow.spacing() / this->support_spacing);
|
this->support_density = std::min(1., this->support_material_flow.spacing() / this->support_spacing);
|
||||||
if (object_config.support_interface_top_layers.value == 0) {
|
if (object_config.support_interface_top_layers.value == 0) {
|
||||||
// No interface layers allowed, print everything with the base support pattern.
|
// No interface layers allowed, print everything with the base support pattern.
|
||||||
this->interface_spacing = this->support_spacing;
|
this->top_interface_spacing = this->support_spacing;
|
||||||
this->interface_density = this->support_density;
|
this->top_interface_density = this->support_density;
|
||||||
}
|
}
|
||||||
|
|
||||||
SupportMaterialPattern support_pattern = object_config.support_base_pattern;
|
SupportMaterialPattern support_pattern = object_config.support_base_pattern;
|
||||||
@@ -114,7 +124,7 @@ struct SupportParameters {
|
|||||||
this->base_fill_pattern =
|
this->base_fill_pattern =
|
||||||
support_pattern == smpHoneycomb ? ipHoneycomb :
|
support_pattern == smpHoneycomb ? ipHoneycomb :
|
||||||
this->support_density > 0.95 || this->with_sheath ? ipRectilinear : ipSupportBase;
|
this->support_density > 0.95 || this->with_sheath ? ipRectilinear : ipSupportBase;
|
||||||
this->interface_fill_pattern = (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
this->interface_fill_pattern = (this->top_interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||||
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
|
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
|
||||||
if (object_config.support_interface_pattern == smipGrid)
|
if (object_config.support_interface_pattern == smipGrid)
|
||||||
this->contact_fill_pattern = ipGrid;
|
this->contact_fill_pattern = ipGrid;
|
||||||
@@ -122,10 +132,10 @@ struct SupportParameters {
|
|||||||
this->contact_fill_pattern = ipRectilinear;
|
this->contact_fill_pattern = ipRectilinear;
|
||||||
else
|
else
|
||||||
this->contact_fill_pattern =
|
this->contact_fill_pattern =
|
||||||
(object_config.support_interface_pattern == smipAuto && slicing_params.soluble_interface) ||
|
(object_config.support_interface_pattern == smipAuto && this->zero_gap_interface_top) ||
|
||||||
object_config.support_interface_pattern == smipConcentric ?
|
object_config.support_interface_pattern == smipConcentric ?
|
||||||
ipConcentric :
|
ipConcentric :
|
||||||
(this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
(this->top_interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||||
|
|
||||||
this->raft_angle_1st_layer = 0.f;
|
this->raft_angle_1st_layer = 0.f;
|
||||||
this->raft_angle_base = 0.f;
|
this->raft_angle_base = 0.f;
|
||||||
@@ -186,10 +196,9 @@ struct SupportParameters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Both top / bottom contacts and interfaces are soluble.
|
// Zero-gap interface flags for top / bottom contact.
|
||||||
bool soluble_interface;
|
bool zero_gap_interface_top;
|
||||||
// Support contact & interface are soluble, but support base is non-soluble.
|
bool zero_gap_interface_bottom;
|
||||||
bool soluble_interface_non_soluble_base;
|
|
||||||
|
|
||||||
// Is there at least a top contact layer extruded above support base?
|
// Is there at least a top contact layer extruded above support base?
|
||||||
bool has_top_contacts;
|
bool has_top_contacts;
|
||||||
@@ -199,9 +208,9 @@ struct SupportParameters {
|
|||||||
size_t num_top_interface_layers;
|
size_t num_top_interface_layers;
|
||||||
// Number of bottom interface layers without counting the contact layer.
|
// Number of bottom interface layers without counting the contact layer.
|
||||||
size_t num_bottom_interface_layers;
|
size_t num_bottom_interface_layers;
|
||||||
// Number of top base interface layers. Zero if not soluble_interface_non_soluble_base.
|
// Number of top base interface layers.
|
||||||
size_t num_top_base_interface_layers;
|
size_t num_top_base_interface_layers;
|
||||||
// Number of bottom base interface layers. Zero if not soluble_interface_non_soluble_base.
|
// Number of bottom base interface layers.
|
||||||
size_t num_bottom_base_interface_layers;
|
size_t num_bottom_base_interface_layers;
|
||||||
|
|
||||||
bool has_contacts() const { return this->has_top_contacts || this->has_bottom_contacts; }
|
bool has_contacts() const { return this->has_top_contacts || this->has_bottom_contacts; }
|
||||||
@@ -233,10 +242,13 @@ struct SupportParameters {
|
|||||||
|
|
||||||
float base_angle;
|
float base_angle;
|
||||||
float interface_angle;
|
float interface_angle;
|
||||||
coordf_t interface_spacing;
|
coordf_t top_interface_spacing;
|
||||||
|
coordf_t bottom_interface_spacing;
|
||||||
coordf_t support_expansion=0;
|
coordf_t support_expansion=0;
|
||||||
// Density of the top / bottom interface and contact layers.
|
// Density of the top interface and contact layers.
|
||||||
coordf_t interface_density;
|
coordf_t top_interface_density;
|
||||||
|
// Density of the bottom interface and contact layers.
|
||||||
|
coordf_t bottom_interface_density;
|
||||||
// Density of the raft interface and contact layers.
|
// Density of the raft interface and contact layers.
|
||||||
coordf_t raft_interface_density;
|
coordf_t raft_interface_density;
|
||||||
coordf_t support_spacing;
|
coordf_t support_spacing;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <tbb/parallel_for_each.h>
|
#include <tbb/parallel_for_each.h>
|
||||||
|
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
#define M_PI 3.1415926535897932384626433832795
|
#define M_PI 3.1415926535897932384626433832795
|
||||||
@@ -73,6 +74,32 @@ inline Point normal(Point pt, double scale)
|
|||||||
|
|
||||||
return pt * (scale / length);
|
return pt * (scale / length);
|
||||||
}
|
}
|
||||||
|
// ORCA:
|
||||||
|
// Collect all polygons of a given SurfaceType from all regions of a layer.
|
||||||
|
// Used for top-contact probing across region/modifier boundaries.
|
||||||
|
static Polygons collect_region_slices_by_type(const Layer &layer, SurfaceType surface_type)
|
||||||
|
{
|
||||||
|
size_t n_polygons_new = 0;
|
||||||
|
|
||||||
|
for (const LayerRegion *region : layer.regions()) {
|
||||||
|
for (const Surface &surface : region->slices.surfaces) {
|
||||||
|
if (surface.surface_type == surface_type)
|
||||||
|
n_polygons_new += surface.expolygon.holes.size() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Polygons out;
|
||||||
|
out.reserve(n_polygons_new);
|
||||||
|
|
||||||
|
for (const LayerRegion *region : layer.regions()) {
|
||||||
|
for (const Surface &surface : region->slices.surfaces) {
|
||||||
|
if (surface.surface_type == surface_type)
|
||||||
|
polygons_append(out, surface.expolygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
enum TreeSupportStage {
|
enum TreeSupportStage {
|
||||||
STAGE_DETECT_OVERHANGS,
|
STAGE_DETECT_OVERHANGS,
|
||||||
@@ -1416,7 +1443,7 @@ void TreeSupport::generate_toolpaths()
|
|||||||
|
|
||||||
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
|
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
|
||||||
Fill* filler_interface = Fill::new_from_type(ipRectilinear);
|
Fill* filler_interface = Fill::new_from_type(ipRectilinear);
|
||||||
filler_interface->angle = PI / 2; // interface should be perpendicular to base
|
filler_interface->angle = M_PI_2; // interface should be perpendicular to base
|
||||||
filler_interface->spacing = support_flow.spacing();
|
filler_interface->spacing = support_flow.spacing();
|
||||||
|
|
||||||
FillParams fill_params;
|
FillParams fill_params;
|
||||||
@@ -1436,7 +1463,7 @@ void TreeSupport::generate_toolpaths()
|
|||||||
SupportLayer *ts_layer = m_object->get_support_layer(layer_nr);
|
SupportLayer *ts_layer = m_object->get_support_layer(layer_nr);
|
||||||
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
|
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
|
||||||
Fill* filler_raft = Fill::new_from_type(ipRectilinear);
|
Fill* filler_raft = Fill::new_from_type(ipRectilinear);
|
||||||
filler_raft->angle = PI / 2;
|
filler_raft->angle = M_PI_2;
|
||||||
filler_raft->spacing = support_flow.spacing();
|
filler_raft->spacing = support_flow.spacing();
|
||||||
for (auto& poly : first_non_raft_base)
|
for (auto& poly : first_non_raft_base)
|
||||||
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::min(size_t(1), wall_count), support_flow, erSupportMaterial, filler_raft, interface_density, false);
|
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::min(size_t(1), wall_count), support_flow, erSupportMaterial, filler_raft, interface_density, false);
|
||||||
@@ -1446,13 +1473,8 @@ void TreeSupport::generate_toolpaths()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BoundingBox bbox_object(Point(-scale_(1.), -scale_(1.0)), Point(scale_(1.), scale_(1.)));
|
BoundingBox bbox_object(Point(-scale_(1.), -scale_(1.0)), Point(scale_(1.), scale_(1.)));
|
||||||
|
// ORCA: base angle used for explicit interlaced interface orientation.
|
||||||
std::shared_ptr<Fill> filler_interface = std::shared_ptr<Fill>(Fill::new_from_type(m_support_params.contact_fill_pattern));
|
const float base_support_angle = Geometry::deg2rad(object_config.support_angle.value);
|
||||||
std::shared_ptr<Fill> filler_Roof1stLayer = std::shared_ptr<Fill>(Fill::new_from_type(ipRectilinear));
|
|
||||||
filler_interface->set_bounding_box(bbox_object);
|
|
||||||
filler_Roof1stLayer->set_bounding_box(bbox_object);
|
|
||||||
filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value + 90.);
|
|
||||||
filler_Roof1stLayer->angle = Geometry::deg2rad(object_config.support_angle.value + 90.);
|
|
||||||
|
|
||||||
// generate tree support tool paths
|
// generate tree support tool paths
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
@@ -1471,17 +1493,28 @@ void TreeSupport::generate_toolpaths()
|
|||||||
coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing();
|
coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing();
|
||||||
coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing);
|
coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing);
|
||||||
ts_layer->support_fills.no_sort = false;
|
ts_layer->support_fills.no_sort = false;
|
||||||
|
// ORCA: per-layer Fill instances to avoid shared-state races during interlaced interfaces.
|
||||||
|
std::shared_ptr<Fill> filler_interface = std::shared_ptr<Fill>(Fill::new_from_type(m_support_params.contact_fill_pattern));
|
||||||
|
std::shared_ptr<Fill> filler_Roof1stLayer = std::shared_ptr<Fill>(Fill::new_from_type(ipRectilinear));
|
||||||
|
filler_interface->set_bounding_box(bbox_object);
|
||||||
|
filler_Roof1stLayer->set_bounding_box(bbox_object);
|
||||||
|
|
||||||
for (auto& area_group : ts_layer->area_groups) {
|
for (auto& area_group : ts_layer->area_groups) {
|
||||||
ExPolygon& poly = *area_group.area;
|
ExPolygon& poly = *area_group.area;
|
||||||
ExPolygons polys;
|
ExPolygons polys;
|
||||||
FillParams fill_params;
|
FillParams fill_params;
|
||||||
|
// ORCA: reset interface Fill state per area group to keep angles deterministic.
|
||||||
|
filler_interface->fixed_angle = false;
|
||||||
|
filler_interface->layer_id = size_t(-1);
|
||||||
|
filler_interface->angle = base_support_angle + M_PI_2; // default interface angle is perpendicular to support angle
|
||||||
if (area_group.type != SupportLayer::BaseType) {
|
if (area_group.type != SupportLayer::BaseType) {
|
||||||
// interface
|
// interface
|
||||||
if (layer_id == 0) {
|
if (layer_id == 0) {
|
||||||
Flow flow = m_raft_layers == 0 ? m_object->print()->brim_flow() : support_flow;
|
Flow flow = m_raft_layers == 0 ? m_object->print()->brim_flow() : support_flow;
|
||||||
|
ExtrusionRole brim_role = (area_group.type == SupportLayer::RoofType && !area_group.interface_as_base) ?
|
||||||
|
erSupportMaterialInterface : erSupportMaterial;
|
||||||
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow,
|
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow,
|
||||||
area_group.type == SupportLayer::RoofType ? erSupportMaterialInterface : erSupportMaterial);
|
brim_role);
|
||||||
polys = std::move(offset_ex(poly, -flow.scaled_spacing()));
|
polys = std::move(offset_ex(poly, -flow.scaled_spacing()));
|
||||||
} else if (area_group.type == SupportLayer::Roof1stLayer) {
|
} else if (area_group.type == SupportLayer::Roof1stLayer) {
|
||||||
polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width()));
|
polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width()));
|
||||||
@@ -1494,12 +1527,18 @@ void TreeSupport::generate_toolpaths()
|
|||||||
}
|
}
|
||||||
if (area_group.type == SupportLayer::Roof1stLayer) {
|
if (area_group.type == SupportLayer::Roof1stLayer) {
|
||||||
// roof_1st_layer
|
// roof_1st_layer
|
||||||
|
// ORCA: Roof1stLayer may be printed with base material when it acts as a contact layer.
|
||||||
|
bool interface_as_base = area_group.interface_as_base;
|
||||||
fill_params.density = interface_density;
|
fill_params.density = interface_density;
|
||||||
// Note: spacing means the separation between two lines as if they are tightly extruded
|
// Note: spacing means the separation between two lines as if they are tightly extruded
|
||||||
filler_Roof1stLayer->spacing = interface_flow.spacing();
|
filler_Roof1stLayer->spacing = interface_flow.spacing();
|
||||||
|
filler_Roof1stLayer->angle = base_support_angle;
|
||||||
|
fill_params.dont_sort = true;
|
||||||
|
Flow interface_base_flow = interface_as_base ? support_flow : interface_flow;
|
||||||
|
ExtrusionRole interface_role = interface_as_base ? erSupportMaterial : erSupportMaterialInterface;
|
||||||
// generate a perimeter first to support interface better
|
// generate a perimeter first to support interface better
|
||||||
ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection();
|
ExtrusionEntityCollection* temp_support_fills = new ExtrusionEntityCollection();
|
||||||
make_perimeter_and_infill(temp_support_fills->entities, poly, 1, interface_flow, erSupportMaterial,
|
make_perimeter_and_infill(temp_support_fills->entities, poly, 1, interface_base_flow, interface_role,
|
||||||
filler_Roof1stLayer.get(), interface_density, false);
|
filler_Roof1stLayer.get(), interface_density, false);
|
||||||
temp_support_fills->no_sort = true; // make sure loops are first
|
temp_support_fills->no_sort = true; // make sure loops are first
|
||||||
if (!temp_support_fills->entities.empty())
|
if (!temp_support_fills->entities.empty())
|
||||||
@@ -1508,23 +1547,49 @@ void TreeSupport::generate_toolpaths()
|
|||||||
delete temp_support_fills;
|
delete temp_support_fills;
|
||||||
} else if (area_group.type == SupportLayer::FloorType) {
|
} else if (area_group.type == SupportLayer::FloorType) {
|
||||||
// floor_areas
|
// floor_areas
|
||||||
|
bool interface_as_base = area_group.interface_as_base;
|
||||||
fill_params.density = bottom_interface_density;
|
fill_params.density = bottom_interface_density;
|
||||||
filler_interface->spacing = interface_flow.spacing();
|
filler_interface->spacing = interface_flow.spacing();
|
||||||
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys,
|
|
||||||
filler_interface.get(), fill_params, erSupportMaterialInterface, interface_flow);
|
|
||||||
} else if (area_group.type == SupportLayer::RoofType) {
|
|
||||||
// roof_areas
|
|
||||||
fill_params.density = interface_density;
|
|
||||||
filler_interface->spacing = interface_flow.spacing();
|
|
||||||
if (m_object_config->support_interface_pattern == smipGrid) {
|
if (m_object_config->support_interface_pattern == smipGrid) {
|
||||||
filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value);
|
filler_interface->angle = base_support_angle;
|
||||||
fill_params.dont_sort = true;
|
fill_params.dont_sort = true;
|
||||||
}
|
}
|
||||||
if (m_object_config->support_interface_pattern == smipRectilinearInterlaced)
|
|
||||||
filler_interface->layer_id = area_group.interface_id;
|
|
||||||
|
|
||||||
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface,
|
if (m_object_config->support_interface_pattern == smipRectilinearInterlaced) {
|
||||||
interface_flow);
|
// ORCA: explicit 0/90 alternation for rectilinear interlaced interfaces.
|
||||||
|
filler_interface->fixed_angle = true;
|
||||||
|
filler_interface->angle = base_support_angle + ((area_group.interface_id & 1) * M_PI_2);
|
||||||
|
fill_params.dont_sort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Flow interface_base_flow = interface_as_base ? support_flow : interface_flow;
|
||||||
|
ExtrusionRole interface_role = interface_as_base ? erSupportMaterial : erSupportMaterialInterface;
|
||||||
|
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys,
|
||||||
|
filler_interface.get(), fill_params, interface_role, interface_base_flow);
|
||||||
|
} else if (area_group.type == SupportLayer::RoofType) {
|
||||||
|
// roof_areas
|
||||||
|
bool interface_as_base = area_group.interface_as_base;
|
||||||
|
fill_params.density = interface_density;
|
||||||
|
filler_interface->spacing = interface_flow.spacing();
|
||||||
|
|
||||||
|
if (m_object_config->support_interface_pattern == smipGrid) {
|
||||||
|
filler_interface->angle = base_support_angle;
|
||||||
|
fill_params.dont_sort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_object_config->support_interface_pattern == smipRectilinearInterlaced) {
|
||||||
|
// ORCA: explicit 0/90 alternation for rectilinear interlaced interfaces.
|
||||||
|
filler_interface->fixed_angle = true;
|
||||||
|
filler_interface->angle = base_support_angle + ((area_group.interface_id & 1) * M_PI_2);
|
||||||
|
fill_params.dont_sort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flow interface_base_flow = interface_as_base ? support_flow : interface_flow;
|
||||||
|
ExtrusionRole interface_role = interface_as_base ? erSupportMaterial : erSupportMaterialInterface;
|
||||||
|
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, interface_role,
|
||||||
|
interface_base_flow);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// base_areas
|
// base_areas
|
||||||
@@ -1890,7 +1955,7 @@ Polygons TreeSupport::get_trim_support_regions(
|
|||||||
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
|
if (!m_slicing_params.zero_gap_interface_top && m_object_config->thick_bridges) {
|
||||||
// Collect all bottom surfaces, which will be extruded with a bridging flow.
|
// Collect all bottom surfaces, which will be extruded with a bridging flow.
|
||||||
for (; i < object.layers().size(); ++i) {
|
for (; i < object.layers().size(); ++i) {
|
||||||
const Layer& object_layer = *object.layers()[i];
|
const Layer& object_layer = *object.layers()[i];
|
||||||
@@ -1919,7 +1984,7 @@ void TreeSupport::draw_circles()
|
|||||||
const PrintObjectConfig &config = m_object->config();
|
const PrintObjectConfig &config = m_object->config();
|
||||||
const Print* print = m_object->print();
|
const Print* print = m_object->print();
|
||||||
bool has_brim = print->has_brim();
|
bool has_brim = print->has_brim();
|
||||||
int bottom_gap_layers = round(m_slicing_params.gap_object_support / m_slicing_params.layer_height);
|
const coordf_t bottom_gap_height = m_slicing_params.gap_object_support;
|
||||||
const coordf_t branch_radius = config.tree_support_branch_diameter.value / 2;
|
const coordf_t branch_radius = config.tree_support_branch_diameter.value / 2;
|
||||||
const coordf_t branch_radius_scaled = scale_(branch_radius);
|
const coordf_t branch_radius_scaled = scale_(branch_radius);
|
||||||
bool on_buildplate_only = m_object_config->support_on_build_plate_only.value;
|
bool on_buildplate_only = m_object_config->support_on_build_plate_only.value;
|
||||||
@@ -1935,7 +2000,7 @@ void TreeSupport::draw_circles()
|
|||||||
{
|
{
|
||||||
double angle;
|
double angle;
|
||||||
if (SQUARE_SUPPORT)
|
if (SQUARE_SUPPORT)
|
||||||
angle = (double) i / CIRCLE_RESOLUTION * TAU + PI / 4.0 + nodes_angle;
|
angle = (double) i / CIRCLE_RESOLUTION * TAU + M_PI_4 + nodes_angle;
|
||||||
else
|
else
|
||||||
angle = (double) i / CIRCLE_RESOLUTION * TAU;
|
angle = (double) i / CIRCLE_RESOLUTION * TAU;
|
||||||
branch_circle.append(Point(cos(angle) * branch_radius_scaled, sin(angle) * branch_radius_scaled));
|
branch_circle.append(Point(cos(angle) * branch_radius_scaled, sin(angle) * branch_radius_scaled));
|
||||||
@@ -1999,7 +2064,7 @@ void TreeSupport::draw_circles()
|
|||||||
coordf_t max_layers_above_base = 0;
|
coordf_t max_layers_above_base = 0;
|
||||||
coordf_t max_layers_above_roof = 0;
|
coordf_t max_layers_above_roof = 0;
|
||||||
coordf_t max_layers_above_roof1 = 0;
|
coordf_t max_layers_above_roof1 = 0;
|
||||||
int interface_id = 0;
|
bool floor_interface_as_base = false;
|
||||||
bool has_circle_node = false;
|
bool has_circle_node = false;
|
||||||
bool need_extra_wall = false;
|
bool need_extra_wall = false;
|
||||||
ExPolygons collision_sharp_tails;
|
ExPolygons collision_sharp_tails;
|
||||||
@@ -2033,6 +2098,8 @@ void TreeSupport::draw_circles()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
const SupportNode& node = *p_node;
|
const SupportNode& node = *p_node;
|
||||||
|
// ORCA: Cap top interface height in mm based on per-node support layer height.
|
||||||
|
const coordf_t top_interface_height = coordf_t(top_interface_layers) * node.height;
|
||||||
ExPolygons area;
|
ExPolygons area;
|
||||||
// Generate directly from overhang polygon if one of the following is true:
|
// Generate directly from overhang polygon if one of the following is true:
|
||||||
// 1) node is a normal part of hybrid support
|
// 1) node is a normal part of hybrid support
|
||||||
@@ -2084,7 +2151,10 @@ void TreeSupport::draw_circles()
|
|||||||
// Merge the overhang into the roof area so tree tips can still produce
|
// Merge the overhang into the roof area so tree tips can still produce
|
||||||
// a continuous support interface. Suppressing this for build-plate-only
|
// a continuous support interface. Suppressing this for build-plate-only
|
||||||
// support drops the roof polygons entirely in valid tree branches.
|
// support drops the roof polygons entirely in valid tree branches.
|
||||||
if (top_interface_layers > 0 && node.support_roof_layers_below > 0 && !node.is_sharp_tail) {
|
// ORCA: Only keep top interface polygons that fully fit in the mm height cap.
|
||||||
|
if (top_interface_layers > 0 && node.support_roof_layers_below > 0 &&
|
||||||
|
(node.dist_mm_to_top - this->top_z_distance) < top_interface_height + EPSILON &&
|
||||||
|
!node.is_sharp_tail) {
|
||||||
ExPolygons overhang_expanded;
|
ExPolygons overhang_expanded;
|
||||||
if (node.overhang.contour.size() > 100 || node.overhang.holes.size()>1)
|
if (node.overhang.contour.size() > 100 || node.overhang.holes.size()>1)
|
||||||
overhang_expanded.emplace_back(node.overhang);
|
overhang_expanded.emplace_back(node.overhang);
|
||||||
@@ -2097,16 +2167,19 @@ void TreeSupport::draw_circles()
|
|||||||
|
|
||||||
if (obj_layer_nr>0 && node.distance_to_top < 0)
|
if (obj_layer_nr>0 && node.distance_to_top < 0)
|
||||||
append(roof_gap_areas, area);
|
append(roof_gap_areas, area);
|
||||||
else if (obj_layer_nr > 0 && node.support_roof_layers_below == 1 && node.is_sharp_tail==false)
|
// ORCA: Roof1stLayer must also fit inside the mm cap.
|
||||||
|
else if (obj_layer_nr > 0 && node.support_roof_layers_below == 1 &&
|
||||||
|
(node.dist_mm_to_top - this->top_z_distance) < top_interface_height + EPSILON && node.is_sharp_tail==false)
|
||||||
{
|
{
|
||||||
append(roof_1st_layer, area);
|
append(roof_1st_layer, area);
|
||||||
max_layers_above_roof1 = std::max(max_layers_above_roof1, node.dist_mm_to_top);
|
max_layers_above_roof1 = std::max(max_layers_above_roof1, node.dist_mm_to_top);
|
||||||
}
|
}
|
||||||
else if (obj_layer_nr > 0 && node.support_roof_layers_below > 0 && node.is_sharp_tail == false)
|
// ORCA: Roof layers must also fit inside the mm cap.
|
||||||
|
else if (obj_layer_nr > 0 && node.support_roof_layers_below > 1 &&
|
||||||
|
(node.dist_mm_to_top - this->top_z_distance) < top_interface_height + EPSILON && node.is_sharp_tail == false)
|
||||||
{
|
{
|
||||||
append(roof_areas, area);
|
append(roof_areas, area);
|
||||||
max_layers_above_roof = std::max(max_layers_above_roof, node.dist_mm_to_top);
|
max_layers_above_roof = std::max(max_layers_above_roof, node.dist_mm_to_top);
|
||||||
interface_id = node.obj_layer_nr % top_interface_layers;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2135,7 +2208,6 @@ void TreeSupport::draw_circles()
|
|||||||
roof_1st_layer.clear();
|
roof_1st_layer.clear();
|
||||||
max_layers_above_roof = std::max(max_layers_above_roof, max_layers_above_roof1);
|
max_layers_above_roof = std::max(max_layers_above_roof, max_layers_above_roof1);
|
||||||
max_layers_above_roof1 = 0;
|
max_layers_above_roof1 = 0;
|
||||||
interface_id = obj_layer_nr % top_interface_layers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExPolygons roofs; append(roofs, roof_1st_layer); append(roofs, roof_areas);append(roofs, roof_gap_areas);
|
ExPolygons roofs; append(roofs, roof_1st_layer); append(roofs, roof_areas);append(roofs, roof_gap_areas);
|
||||||
@@ -2148,37 +2220,130 @@ void TreeSupport::draw_circles()
|
|||||||
for (auto &area : base_areas) { area.simplify(scale_(line_width / 2), &base_areas_simplified); }
|
for (auto &area : base_areas) { area.simplify(scale_(line_width / 2), &base_areas_simplified); }
|
||||||
base_areas = std::move(base_areas_simplified);
|
base_areas = std::move(base_areas_simplified);
|
||||||
}
|
}
|
||||||
//Subtract support floors. We can only compute floor_areas here instead of with roof_areas,
|
// ORCA:
|
||||||
// or we'll get much wider floor than necessary.
|
// Bottom interface / bottom gap must be anchored to the *true* support-to-model contact surface.
|
||||||
if (bottom_interface_layers + bottom_gap_layers > 0)
|
// Do NOT window the contact search by gap or interface height.
|
||||||
|
// First find the real contact below, then enforce:
|
||||||
|
// - an empty gap below (contact_z + gap)
|
||||||
|
// - exactly N interface layers above that
|
||||||
|
if (!base_areas.empty() && !m_object_config->support_on_build_plate_only.value &&
|
||||||
|
(bottom_gap_height > EPSILON || bottom_interface_layers > 0))
|
||||||
{
|
{
|
||||||
if (layer_nr >= bottom_interface_layers + bottom_gap_layers)
|
const coordf_t interface_height =
|
||||||
{
|
bottom_interface_layers > 0 ? coordf_t(bottom_interface_layers) * m_slicing_params.layer_height : 0.0;
|
||||||
// find the lowest interface layer
|
|
||||||
// TODO the gap may not be exact when "independent support layer height" is enabled
|
const coordf_t layer_top_z = ts_layer->print_z;
|
||||||
size_t layer_nr_next = layer_nr - bottom_interface_layers;
|
const coordf_t layer_bottom_z = ts_layer->bottom_z();
|
||||||
size_t obj_layer_nr_next = m_ts_data->layer_heights[layer_nr_next].obj_layer_nr;
|
ExPolygons new_base_areas;
|
||||||
for (size_t i = 0; i <= bottom_gap_layers && i <= obj_layer_nr_next; i++)
|
ExPolygons new_floor_areas;
|
||||||
{
|
struct ContactBand {
|
||||||
const Layer *below_layer = m_object->get_layer(obj_layer_nr_next - i);
|
coordf_t z = 0.0;
|
||||||
ExPolygons bottom_interface = intersection_ex(base_areas, below_layer->lslices);
|
Polygons surfaces;
|
||||||
floor_areas.insert(floor_areas.end(), bottom_interface.begin(), bottom_interface.end());
|
};
|
||||||
|
for (const ExPolygon& comp : base_areas) {
|
||||||
|
ExPolygons comp_poly { comp };
|
||||||
|
bool found_contact = false;
|
||||||
|
std::vector<ContactBand> bands;
|
||||||
|
|
||||||
|
// Search downward for object layers whose TOP/BOTTOM surfaces intersect this component.
|
||||||
|
for (size_t idx = obj_layer_nr + 1; idx-- > 0;) {
|
||||||
|
const Layer* below_layer = m_object->get_layer(idx);
|
||||||
|
Polygons top_surfaces = collect_region_slices_by_type(*below_layer, stTop);
|
||||||
|
Polygons bottom_surfaces = collect_region_slices_by_type(*below_layer, stBottom);
|
||||||
|
Polygons surf_union = top_surfaces;
|
||||||
|
polygons_append(surf_union, bottom_surfaces);
|
||||||
|
if (surf_union.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExPolygons inter = intersection_ex(comp_poly, surf_union);
|
||||||
|
if (!inter.empty()) {
|
||||||
|
bands.push_back(ContactBand{ below_layer->print_z, std::move(surf_union) });
|
||||||
|
found_contact = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (floor_areas.empty() == false) {
|
|
||||||
//floor_areas = std::move(diff_ex(floor_areas, avoid_region_interface));
|
if (found_contact) {
|
||||||
//floor_areas = std::move(offset2_ex(floor_areas, contact_dist_scaled, -contact_dist_scaled));
|
std::sort(bands.begin(), bands.end(), [](const ContactBand &a, const ContactBand &b) {
|
||||||
base_areas = std::move(diff_ex(base_areas, offset_ex(floor_areas, 10)));
|
return a.z < b.z;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_contact) {
|
||||||
|
append(new_base_areas, comp_poly);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool interface_id_set = false;
|
||||||
|
bool any_gap_cleared = false;
|
||||||
|
|
||||||
|
for (const ContactBand &band : bands) {
|
||||||
|
const coordf_t band_gap_top = band.z + bottom_gap_height;
|
||||||
|
const coordf_t band_iface_start = band_gap_top;
|
||||||
|
const bool band_applies = layer_top_z >= band.z - EPSILON;
|
||||||
|
if (!band_applies)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
// Inside the gap: remove only the part overlapping the contact surface, keep the rest.
|
||||||
|
if (bottom_gap_height > EPSILON && layer_bottom_z < band_gap_top - EPSILON) {
|
||||||
|
any_gap_cleared = true;
|
||||||
|
comp_poly = std::move(diff_ex(comp_poly, band.surfaces));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overlaps interface band
|
||||||
|
if (bottom_interface_layers > 0 &&
|
||||||
|
layer_bottom_z >= band_iface_start - EPSILON &&
|
||||||
|
layer_bottom_z < band_iface_start + interface_height - EPSILON) {
|
||||||
|
if (!interface_id_set) {
|
||||||
|
size_t first_interface_layer = layer_nr;
|
||||||
|
while (first_interface_layer > 0) {
|
||||||
|
if (m_ts_data->layer_heights[first_interface_layer - 1].print_z <= band_iface_start + EPSILON)
|
||||||
|
break;
|
||||||
|
--first_interface_layer;
|
||||||
|
}
|
||||||
|
// ORCA: Use support-layer index for base-interface selection (robust with independent heights).
|
||||||
|
if (m_support_params.num_bottom_base_interface_layers > 0) {
|
||||||
|
const int bottom_interface_idx =
|
||||||
|
std::max(0, int(layer_nr) - int(first_interface_layer));
|
||||||
|
const int bottom_base_start_idx =
|
||||||
|
std::max(0, int(bottom_interface_layers) - int(m_support_params.num_bottom_base_interface_layers));
|
||||||
|
floor_interface_as_base = bottom_interface_idx >= bottom_base_start_idx;
|
||||||
|
}
|
||||||
|
interface_id_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExPolygons band_ex = union_ex(band.surfaces);
|
||||||
|
if (!band_ex.empty()) {
|
||||||
|
const coordf_t margin = scale_(m_support_params.support_extrusion_width);
|
||||||
|
ExPolygons comp_margin = offset_ex(comp_poly, margin);
|
||||||
|
ExPolygons band_clipped = intersection_ex(band_ex, comp_margin);
|
||||||
|
band_ex = std::move(band_clipped);
|
||||||
|
}
|
||||||
|
ExPolygons comp_interface = band_ex.empty() ? ExPolygons {} : intersection_ex(comp_poly, band_ex);
|
||||||
|
if (!comp_interface.empty()) {
|
||||||
|
append(new_floor_areas, comp_interface);
|
||||||
|
comp_poly = std::move(diff_ex(comp_poly, offset_ex(comp_interface, 10)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bottom_gap_layers > 0 && m_ts_data->layer_heights[layer_nr].obj_layer_nr > bottom_gap_layers) {
|
|
||||||
const Layer* below_layer = m_object->get_layer(m_ts_data->layer_heights[layer_nr].obj_layer_nr - bottom_gap_layers);
|
|
||||||
ExPolygons bottom_gap_area = intersection_ex(floor_areas, below_layer->lslices);
|
|
||||||
if (!bottom_gap_area.empty()) {
|
|
||||||
floor_areas = std::move(diff_ex(floor_areas, bottom_gap_area));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (any_gap_cleared && comp_poly.empty()) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!comp_poly.empty())
|
||||||
|
append(new_base_areas, comp_poly);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
base_areas = std::move(new_base_areas);
|
||||||
|
floor_areas = std::move(new_floor_areas);
|
||||||
|
}
|
||||||
|
|
||||||
auto &area_groups = ts_layer->area_groups;
|
auto &area_groups = ts_layer->area_groups;
|
||||||
|
|
||||||
for (auto& expoly : ts_layer->base_areas) {
|
for (auto& expoly : ts_layer->base_areas) {
|
||||||
//if (area(expoly) < SQ(scale_(1))) continue;
|
//if (area(expoly) < SQ(scale_(1))) continue;
|
||||||
area_groups.emplace_back(&expoly, SupportLayer::BaseType, max_layers_above_base);
|
area_groups.emplace_back(&expoly, SupportLayer::BaseType, max_layers_above_base);
|
||||||
@@ -2188,11 +2353,11 @@ void TreeSupport::draw_circles()
|
|||||||
for (auto& expoly : ts_layer->roof_areas) {
|
for (auto& expoly : ts_layer->roof_areas) {
|
||||||
//if (area(expoly) < SQ(scale_(1))) continue;
|
//if (area(expoly) < SQ(scale_(1))) continue;
|
||||||
area_groups.emplace_back(&expoly, SupportLayer::RoofType, max_layers_above_roof);
|
area_groups.emplace_back(&expoly, SupportLayer::RoofType, max_layers_above_roof);
|
||||||
area_groups.back().interface_id = interface_id;
|
|
||||||
}
|
}
|
||||||
for (auto &expoly : ts_layer->floor_areas) {
|
for (auto &expoly : ts_layer->floor_areas) {
|
||||||
//if (area(expoly) < SQ(scale_(1))) continue;
|
//if (area(expoly) < SQ(scale_(1))) continue;
|
||||||
area_groups.emplace_back(&expoly, SupportLayer::FloorType, 10000);
|
area_groups.emplace_back(&expoly, SupportLayer::FloorType, 10000);
|
||||||
|
area_groups.back().interface_as_base = floor_interface_as_base;
|
||||||
}
|
}
|
||||||
for (auto &expoly : ts_layer->roof_1st_layer) {
|
for (auto &expoly : ts_layer->roof_1st_layer) {
|
||||||
//if (area(expoly) < SQ(scale_(1))) continue;
|
//if (area(expoly) < SQ(scale_(1))) continue;
|
||||||
@@ -2216,13 +2381,49 @@ void TreeSupport::draw_circles()
|
|||||||
//Must update bounding box which is used in avoid crossing perimeter
|
//Must update bounding box which is used in avoid crossing perimeter
|
||||||
ts_layer->lslices_bboxes.clear();
|
ts_layer->lslices_bboxes.clear();
|
||||||
ts_layer->lslices_bboxes.reserve(ts_layer->lslices.size());
|
ts_layer->lslices_bboxes.reserve(ts_layer->lslices.size());
|
||||||
|
|
||||||
for (const ExPolygon& expoly : ts_layer->lslices)
|
for (const ExPolygon& expoly : ts_layer->lslices)
|
||||||
ts_layer->lslices_bboxes.emplace_back(get_extents(expoly));
|
ts_layer->lslices_bboxes.emplace_back(get_extents(expoly));
|
||||||
|
|
||||||
ts_layer->backup_untyped_slices();
|
ts_layer->backup_untyped_slices();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// ORCA: normalize interface_id sequencing to follow printed interface layers only.
|
||||||
|
const int top_base_layers = int(m_support_params.num_top_base_interface_layers);
|
||||||
|
const bool interlaced = m_object_config->support_interface_pattern == smipRectilinearInterlaced;
|
||||||
|
int roof_interface_id = 0;
|
||||||
|
int floor_interface_id = 0;
|
||||||
|
bool has_roof_interface;
|
||||||
|
bool has_floor_interface;
|
||||||
|
|
||||||
|
for (size_t layer_nr = 0; layer_nr < m_ts_data->layer_heights.size(); ++layer_nr) {
|
||||||
|
SupportLayer *ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
|
||||||
|
if (ts_layer == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
has_roof_interface = false;
|
||||||
|
has_floor_interface = false;
|
||||||
|
|
||||||
|
for (auto &area_group : ts_layer->area_groups) {
|
||||||
|
if (area_group.type == SupportLayer::RoofType || area_group.type == SupportLayer::Roof1stLayer) {
|
||||||
|
if (interlaced)
|
||||||
|
area_group.interface_id = roof_interface_id;
|
||||||
|
area_group.interface_as_base = top_base_layers > 0 && roof_interface_id < top_base_layers;
|
||||||
|
has_roof_interface = true;
|
||||||
|
} else if (area_group.type == SupportLayer::FloorType) {
|
||||||
|
if (interlaced)
|
||||||
|
area_group.interface_id = floor_interface_id;
|
||||||
|
has_floor_interface = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_roof_interface)
|
||||||
|
++roof_interface_id;
|
||||||
|
|
||||||
|
if (has_floor_interface)
|
||||||
|
++floor_interface_id;
|
||||||
|
}
|
||||||
|
|
||||||
if (with_lightning_infill)
|
if (with_lightning_infill)
|
||||||
{
|
{
|
||||||
@@ -2488,6 +2689,7 @@ void TreeSupport::drop_nodes()
|
|||||||
layer_radius.emplace(calc_radius(node_dist));
|
layer_radius.emplace(calc_radius(node_dist));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parallel pre-compute avoidance
|
// parallel pre-compute avoidance
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, contact_nodes.size() - 1), [&](const tbb::blocked_range<size_t> &range) {
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, contact_nodes.size() - 1), [&](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++) {
|
for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++) {
|
||||||
@@ -2679,8 +2881,9 @@ void TreeSupport::drop_nodes()
|
|||||||
// Make sure the next pass doesn't drop down either of these (since that already happened).
|
// Make sure the next pass doesn't drop down either of these (since that already happened).
|
||||||
node_parent->merged_neighbours.push_front(node_parent == p_node ? neighbour : p_node);
|
node_parent->merged_neighbours.push_front(node_parent == p_node ? neighbour : p_node);
|
||||||
const bool to_buildplate = !is_inside_ex(get_collision(0, obj_layer_nr_next), next_position);
|
const bool to_buildplate = !is_inside_ex(get_collision(0, obj_layer_nr_next), next_position);
|
||||||
SupportNode* next_node = m_ts_data->create_node(next_position, node_parent->distance_to_top + 1, obj_layer_nr_next, node_parent->support_roof_layers_below - 1, to_buildplate, node_parent,
|
SupportNode* next_node = m_ts_data->create_node(next_position, node_parent->distance_to_top + 1, obj_layer_nr_next,
|
||||||
print_z_next, height_next);
|
node_parent->support_roof_layers_below - (node_parent->distance_to_top > 0 ? 1 : 0),
|
||||||
|
to_buildplate, node_parent, print_z_next, height_next);
|
||||||
get_max_move_dist(next_node);
|
get_max_move_dist(next_node);
|
||||||
m_ts_data->m_mutex.lock();
|
m_ts_data->m_mutex.lock();
|
||||||
contact_nodes[layer_nr_next].push_back(next_node);
|
contact_nodes[layer_nr_next].push_back(next_node);
|
||||||
@@ -2730,7 +2933,8 @@ void TreeSupport::drop_nodes()
|
|||||||
ExPolygons overhangs_next = diff_clipped({ node.overhang }, get_collision(0, obj_layer_nr_next));
|
ExPolygons overhangs_next = diff_clipped({ node.overhang }, get_collision(0, obj_layer_nr_next));
|
||||||
for(auto& overhang:overhangs_next) {
|
for(auto& overhang:overhangs_next) {
|
||||||
Point next_pt = overhang.contour.centroid();
|
Point next_pt = overhang.contour.centroid();
|
||||||
SupportNode *next_node = m_ts_data->create_node(next_pt, p_node->distance_to_top + 1, obj_layer_nr_next, p_node->support_roof_layers_below - 1,
|
SupportNode *next_node = m_ts_data->create_node(next_pt, p_node->distance_to_top + 1, obj_layer_nr_next,
|
||||||
|
p_node->support_roof_layers_below - (p_node->distance_to_top > 0 ? 1 : 0),
|
||||||
to_buildplate, p_node, print_z_next, height_next);
|
to_buildplate, p_node, print_z_next, height_next);
|
||||||
next_node->max_move_dist = 0;
|
next_node->max_move_dist = 0;
|
||||||
next_node->overhang = std::move(overhang);
|
next_node->overhang = std::move(overhang);
|
||||||
@@ -2876,8 +3080,9 @@ void TreeSupport::drop_nodes()
|
|||||||
}
|
}
|
||||||
auto next_collision = get_collision(0, obj_layer_nr_next);
|
auto next_collision = get_collision(0, obj_layer_nr_next);
|
||||||
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[obj_layer_nr_next], next_layer_vertex);
|
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[obj_layer_nr_next], next_layer_vertex);
|
||||||
SupportNode * next_node = m_ts_data->create_node(next_layer_vertex, node.distance_to_top + 1, obj_layer_nr_next, node.support_roof_layers_below - 1, to_buildplate, p_node,
|
SupportNode * next_node = m_ts_data->create_node(next_layer_vertex, node.distance_to_top + 1, obj_layer_nr_next,
|
||||||
print_z_next, height_next);
|
node.support_roof_layers_below - (node.distance_to_top > 0 ? 1 : 0),
|
||||||
|
to_buildplate, p_node, print_z_next, height_next);
|
||||||
// don't increase radius if next node will collide partially with the object (STUDIO-7883)
|
// don't increase radius if next node will collide partially with the object (STUDIO-7883)
|
||||||
to_outside = projection_onto(next_collision, next_node->position);
|
to_outside = projection_onto(next_collision, next_node->position);
|
||||||
direction_to_outer = to_outside - node.position;
|
direction_to_outer = to_outside - node.position;
|
||||||
@@ -3098,7 +3303,12 @@ std::vector<LayerHeightData> TreeSupport::plan_layer_heights()
|
|||||||
// add support layers according to layer_heights
|
// add support layers according to layer_heights
|
||||||
int support_layer_nr = m_raft_layers;
|
int support_layer_nr = m_raft_layers;
|
||||||
for (size_t i = 0; i < layer_heights.size(); i++, support_layer_nr++) {
|
for (size_t i = 0; i < layer_heights.size(); i++, support_layer_nr++) {
|
||||||
SupportLayer *ts_layer = m_object->add_tree_support_layer(support_layer_nr, layer_heights[i].print_z, layer_heights[i].height, layer_heights[i].print_z);
|
// SupportLayer *ts_layer = m_object->add_tree_support_layer(support_layer_nr, layer_heights[i].print_z, layer_heights[i].height, layer_heights[i].print_z);
|
||||||
|
|
||||||
|
// ORCA: add_tree_support_layer() argument order is (id, height, print_z, slice_z).
|
||||||
|
// Passing print_z as height breaks support layer geometry.
|
||||||
|
SupportLayer *ts_layer = m_object->add_tree_support_layer(support_layer_nr, layer_heights[i].height, layer_heights[i].print_z, layer_heights[i].print_z);
|
||||||
|
|
||||||
if (ts_layer->id() > m_raft_layers) {
|
if (ts_layer->id() > m_raft_layers) {
|
||||||
SupportLayer *lower_layer = m_object->get_support_layer(ts_layer->id() - 1);
|
SupportLayer *lower_layer = m_object->get_support_layer(ts_layer->id() - 1);
|
||||||
if (lower_layer) {
|
if (lower_layer) {
|
||||||
@@ -3147,7 +3357,21 @@ std::vector<LayerHeightData> TreeSupport::plan_layer_heights()
|
|||||||
for (SupportNode *node : contact_nodes[layer_nr]) {
|
for (SupportNode *node : contact_nodes[layer_nr]) {
|
||||||
node->height = new_height;
|
node->height = new_height;
|
||||||
node->distance_to_top = -num_layers;
|
node->distance_to_top = -num_layers;
|
||||||
node->support_roof_layers_below += num_layers - 1;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORCA: Recompute support_roof_layers_below from remaining interface height (independent heights).
|
||||||
|
const int top_layers = m_object->config().support_interface_top_layers.value;
|
||||||
|
if (m_support_params.independent_layer_height && top_layers > 0) {
|
||||||
|
const coordf_t interface_height_mm = coordf_t(top_layers) * m_slicing_params.layer_height;
|
||||||
|
for (int layer_nr = 0; layer_nr < contact_nodes.size(); layer_nr++) {
|
||||||
|
if (contact_nodes[layer_nr].empty()) continue;
|
||||||
|
for (SupportNode *node : contact_nodes[layer_nr]) {
|
||||||
|
if (node->height <= EPSILON) continue;
|
||||||
|
const coordf_t remaining_mm = interface_height_mm - (node->dist_mm_to_top - this->top_z_distance);
|
||||||
|
const int layers_fit = remaining_mm < -EPSILON ? 0 : int(std::floor((remaining_mm + EPSILON) / node->height));
|
||||||
|
node->support_roof_layers_below = std::min(layers_fit, top_layers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3166,9 +3390,6 @@ void TreeSupport::generate_contact_points()
|
|||||||
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
|
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
|
||||||
coord_t radius_scaled = scale_(base_radius);
|
coord_t radius_scaled = scale_(base_radius);
|
||||||
bool on_buildplate_only = m_object_config->support_on_build_plate_only.value;
|
bool on_buildplate_only = m_object_config->support_on_build_plate_only.value;
|
||||||
const bool roof_enabled = config.support_interface_top_layers.value > 0;
|
|
||||||
const bool force_tip_to_roof = roof_enabled && m_support_params.soluble_interface;
|
|
||||||
|
|
||||||
//First generate grid points to cover the entire area of the print.
|
//First generate grid points to cover the entire area of the print.
|
||||||
BoundingBox bounding_box = m_object->bounding_box();
|
BoundingBox bounding_box = m_object->bounding_box();
|
||||||
const Point bounding_box_size = bounding_box.max - bounding_box.min;
|
const Point bounding_box_size = bounding_box.max - bounding_box.min;
|
||||||
@@ -3200,7 +3421,7 @@ void TreeSupport::generate_contact_points()
|
|||||||
// z_distance_top = round(z_distance_top / layer_height) * layer_height;
|
// z_distance_top = round(z_distance_top / layer_height) * layer_height;
|
||||||
// // BBS: add extra distance if thick bridge is enabled
|
// // BBS: add extra distance if thick bridge is enabled
|
||||||
// // Note: normal support uses print_z, but tree support uses integer layers, so we need to subtract layer_height
|
// // Note: normal support uses print_z, but tree support uses integer layers, so we need to subtract layer_height
|
||||||
// if (!m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
|
// if (!m_slicing_params.zero_gap_interface_top && m_object_config->thick_bridges) {
|
||||||
// z_distance_top += m_object->layers()[0]->regions()[0]->region().bridging_height_avg(m_object->print()->config()) - layer_height;
|
// z_distance_top += m_object->layers()[0]->regions()[0]->region().bridging_height_avg(m_object->print()->config()) - layer_height;
|
||||||
//}
|
//}
|
||||||
// }
|
// }
|
||||||
@@ -3208,8 +3429,6 @@ void TreeSupport::generate_contact_points()
|
|||||||
int gap_layers = z_distance_top == 0 ? 0 : 1;
|
int gap_layers = z_distance_top == 0 ? 0 : 1;
|
||||||
|
|
||||||
size_t support_roof_layers = config.support_interface_top_layers.value;
|
size_t support_roof_layers = config.support_interface_top_layers.value;
|
||||||
if (support_roof_layers > 0)
|
|
||||||
support_roof_layers += 1; // BBS: add a normal support layer below interface (if we have interface)
|
|
||||||
coordf_t thresh_angle = std::min(89.f, config.support_threshold_angle.value < EPSILON ? 30.f : config.support_threshold_angle.value);
|
coordf_t thresh_angle = std::min(89.f, config.support_threshold_angle.value < EPSILON ? 30.f : config.support_threshold_angle.value);
|
||||||
coordf_t half_overhang_distance = scale_(tan(thresh_angle * M_PI / 180.0) * layer_height / 2);
|
coordf_t half_overhang_distance = scale_(tan(thresh_angle * M_PI / 180.0) * layer_height / 2);
|
||||||
|
|
||||||
@@ -3263,13 +3482,13 @@ void TreeSupport::generate_contact_points()
|
|||||||
if (force_add || !already_inserted.count(hash_pos)) {
|
if (force_add || !already_inserted.count(hash_pos)) {
|
||||||
already_inserted.emplace(hash_pos);
|
already_inserted.emplace(hash_pos);
|
||||||
bool to_buildplate = true;
|
bool to_buildplate = true;
|
||||||
size_t roof_layers = add_interface ? support_roof_layers : 0;
|
size_t roof_layers = add_interface ? (support_roof_layers > 0 ? support_roof_layers - 1 : 0) : 0; // subtract 1 because the contact node itself counts as one layer
|
||||||
// add a new node as a virtual node which acts as the invisible gap between support and object
|
// add a new node as a virtual node which acts as the invisible gap between support and object
|
||||||
// distance_to_top=-1: it's virtual
|
// distance_to_top=-1: it's virtual
|
||||||
// print_z=object_layer->bottom_z: it directly contacts the bottom
|
// print_z=object_layer->bottom_z: it directly contacts the bottom
|
||||||
// height=z_distance_top: it's height is exactly the gap distance
|
// height=z_distance_top: it's height is exactly the gap distance
|
||||||
// dist_mm_to_top=0: it directly contacts the bottom
|
// dist_mm_to_top=0: it directly contacts the bottom
|
||||||
contact_node = m_ts_data->create_node(pt, -gap_layers, layer_nr-1, roof_layers + 1, to_buildplate, SupportNode::NO_PARENT, bottom_z, z_distance_top, 0,
|
contact_node = m_ts_data->create_node(pt, -gap_layers, layer_nr-1, roof_layers, to_buildplate, SupportNode::NO_PARENT, bottom_z, z_distance_top, 0,
|
||||||
radius);
|
radius);
|
||||||
contact_node->overhang = overhang;
|
contact_node->overhang = overhang;
|
||||||
contact_node->is_sharp_tail = is_sharp_tail;
|
contact_node->is_sharp_tail = is_sharp_tail;
|
||||||
@@ -3305,7 +3524,7 @@ void TreeSupport::generate_contact_points()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &overhang : overhangs_regular) {
|
for (auto &overhang : overhangs_regular) {
|
||||||
bool add_interface = (force_tip_to_roof || area(overhang) > minimum_roof_area) && !is_sharp_tail;
|
bool add_interface = area(overhang) > minimum_roof_area && !is_sharp_tail;
|
||||||
BoundingBox overhang_bounds = get_extents(overhang);
|
BoundingBox overhang_bounds = get_extents(overhang);
|
||||||
double radius = std::clamp(unscale_(overhang_bounds.radius()), MIN_BRANCH_RADIUS, base_radius);
|
double radius = std::clamp(unscale_(overhang_bounds.radius()), MIN_BRANCH_RADIUS, base_radius);
|
||||||
// add supports at corners for both auto and manual overhangs, github #2008
|
// add supports at corners for both auto and manual overhangs, github #2008
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fstream>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -54,7 +53,6 @@
|
|||||||
#define _L(s) Slic3r::I18N::translate(s)
|
#define _L(s) Slic3r::I18N::translate(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define TREESUPPORT_DEBUG_SVG
|
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
@@ -132,7 +130,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
|||||||
const PrintObjectConfig &object_config = print_object.config();
|
const PrintObjectConfig &object_config = print_object.config();
|
||||||
if (object_config.support_top_z_distance < EPSILON)
|
if (object_config.support_top_z_distance < EPSILON)
|
||||||
// || min_feature_size < scaled<coord_t>(0.1) that is the minimum line width
|
// || min_feature_size < scaled<coord_t>(0.1) that is the minimum line width
|
||||||
TreeSupportSettings::soluble = true;
|
TreeSupportSettings::zero_top_z_gap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t largest_printed_mesh_idx = 0;
|
size_t largest_printed_mesh_idx = 0;
|
||||||
@@ -283,16 +281,6 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
|
|||||||
//FIXME enforcer_overhang_offset is a fudge constant!
|
//FIXME enforcer_overhang_offset is a fudge constant!
|
||||||
enforced_overhangs = diff(offset(union_ex(enforced_overhangs), enforcer_overhang_offset),
|
enforced_overhangs = diff(offset(union_ex(enforced_overhangs), enforcer_overhang_offset),
|
||||||
lower_layer.lslices);
|
lower_layer.lslices);
|
||||||
#ifdef TREESUPPORT_DEBUG_SVG
|
|
||||||
// if (! intersecting_edges(enforced_overhangs).empty())
|
|
||||||
{
|
|
||||||
static int irun = 0;
|
|
||||||
SVG::export_expolygons(debug_out_path("treesupport-self-intersections-%d.svg", ++irun),
|
|
||||||
{ { { current_layer.lslices }, { "current_layer.lslices", "yellow", 0.5f } },
|
|
||||||
{ { lower_layer.lslices }, { "lower_layer.lslices", "gray", 0.5f } },
|
|
||||||
{ { union_ex(enforced_overhangs) }, { "enforced_overhangs", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
|
||||||
}
|
|
||||||
#endif // TREESUPPORT_DEBUG_SVG
|
|
||||||
//check_self_intersections(enforced_overhangs, "generate_overhangs - enforced overhangs2");
|
//check_self_intersections(enforced_overhangs, "generate_overhangs - enforced overhangs2");
|
||||||
overhangs = overhangs.empty() ? std::move(enforced_overhangs) : union_(overhangs, enforced_overhangs);
|
overhangs = overhangs.empty() ? std::move(enforced_overhangs) : union_(overhangs, enforced_overhangs);
|
||||||
//check_self_intersections(overhangs, "generate_overhangs - enforcers");
|
//check_self_intersections(overhangs, "generate_overhangs - enforcers");
|
||||||
@@ -718,7 +706,8 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
|
|||||||
(support_params.interface_angle + (layer_idx & 1) ? float(- M_PI / 4.) : float(+ M_PI / 4.)) :
|
(support_params.interface_angle + (layer_idx & 1) ? float(- M_PI / 4.) : float(+ M_PI / 4.)) :
|
||||||
support_params.base_angle;
|
support_params.base_angle;
|
||||||
|
|
||||||
fill_params.density = float(roof ? support_params.interface_density : scaled<float>(filler->spacing) / (scaled<float>(filler->spacing) + float(support_infill_distance)));
|
// ORCA: use top-specific interface density after separating top/bottom settings.
|
||||||
|
fill_params.density = float(roof ? support_params.top_interface_density : scaled<float>(filler->spacing) / (scaled<float>(filler->spacing) + float(support_infill_distance)));
|
||||||
fill_params.dont_adjust = true;
|
fill_params.dont_adjust = true;
|
||||||
|
|
||||||
Polylines out;
|
Polylines out;
|
||||||
@@ -1291,7 +1280,7 @@ static void generate_initial_areas(
|
|||||||
;
|
;
|
||||||
const size_t num_support_roof_layers = mesh_group_settings.support_roof_layers;
|
const size_t num_support_roof_layers = mesh_group_settings.support_roof_layers;
|
||||||
const bool roof_enabled = num_support_roof_layers > 0;
|
const bool roof_enabled = num_support_roof_layers > 0;
|
||||||
const bool force_tip_to_roof = roof_enabled && (interface_placer.support_parameters.soluble_interface || sqr<double>(config.min_radius) * M_PI > mesh_group_settings.minimum_roof_area);
|
const bool force_tip_to_roof = roof_enabled && (interface_placer.support_parameters.zero_gap_interface_top || sqr<double>(config.min_radius) * M_PI > mesh_group_settings.minimum_roof_area);
|
||||||
// cap for how much layer below the overhang a new support point may be added, as other than with regular support every new inserted point
|
// cap for how much layer below the overhang a new support point may be added, as other than with regular support every new inserted point
|
||||||
// may cause extra material and time cost. Could also be an user setting or differently calculated. Idea is that if an overhang
|
// may cause extra material and time cost. Could also be an user setting or differently calculated. Idea is that if an overhang
|
||||||
// does not turn valid in double the amount of layers a slope of support angle would take to travel xy_distance, nothing reasonable will come from it.
|
// does not turn valid in double the amount of layers a slope of support angle would take to travel xy_distance, nothing reasonable will come from it.
|
||||||
@@ -1806,11 +1795,6 @@ static void increase_areas_one_layer(
|
|||||||
// Abstract representation of the model outline. If an influence area would move through it, it could teleport through a wall.
|
// Abstract representation of the model outline. If an influence area would move through it, it could teleport through a wall.
|
||||||
volumes.getWallRestriction(support_element_collision_radius(config, parent.state), layer_idx, parent.state.use_min_xy_dist);
|
volumes.getWallRestriction(support_element_collision_radius(config, parent.state), layer_idx, parent.state.use_min_xy_dist);
|
||||||
|
|
||||||
#ifdef TREESUPPORT_DEBUG_SVG
|
|
||||||
SVG::export_expolygons(debug_out_path("treesupport-increase_areas_one_layer-%d-%ld.svg", layer_idx, int(merging_area_idx)),
|
|
||||||
{ { { union_ex(wall_restriction) }, { "wall_restricrictions", "gray", 0.5f } },
|
|
||||||
{ { union_ex(parent.influence_area) }, { "parent", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
|
||||||
#endif // TREESUPPORT_DEBUG_SVG
|
|
||||||
|
|
||||||
Polygons to_bp_data, to_model_data;
|
Polygons to_bp_data, to_model_data;
|
||||||
coord_t radius = support_element_collision_radius(config, elem);
|
coord_t radius = support_element_collision_radius(config, elem);
|
||||||
@@ -1941,11 +1925,6 @@ static void increase_areas_one_layer(
|
|||||||
// was never made for precision in the single digit micron range.
|
// was never made for precision in the single digit micron range.
|
||||||
offset_slow = safe_offset_inc(parent.influence_area, extra_speed + extra_slow_speed + config.maximum_move_distance_slow,
|
offset_slow = safe_offset_inc(parent.influence_area, extra_speed + extra_slow_speed + config.maximum_move_distance_slow,
|
||||||
wall_restriction, safe_movement_distance, offset_independant_faster ? safe_movement_distance + radius : 0, 2);
|
wall_restriction, safe_movement_distance, offset_independant_faster ? safe_movement_distance + radius : 0, 2);
|
||||||
#ifdef TREESUPPORT_DEBUG_SVG
|
|
||||||
SVG::export_expolygons(debug_out_path("treesupport-increase_areas_one_layer-slow-%d-%ld.svg", layer_idx, int(merging_area_idx)),
|
|
||||||
{ { { union_ex(wall_restriction) }, { "wall_restricrictions", "gray", 0.5f } },
|
|
||||||
{ { union_ex(offset_slow) }, { "offset_slow", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
|
||||||
#endif // TREESUPPORT_DEBUG_SVG
|
|
||||||
}
|
}
|
||||||
if (offset_fast.empty() && settings.increase_speed != slow_speed) {
|
if (offset_fast.empty() && settings.increase_speed != slow_speed) {
|
||||||
if (offset_independant_faster)
|
if (offset_independant_faster)
|
||||||
@@ -1955,11 +1934,6 @@ static void increase_areas_one_layer(
|
|||||||
const coord_t delta_slow_fast = config.maximum_move_distance - (config.maximum_move_distance_slow + extra_slow_speed);
|
const coord_t delta_slow_fast = config.maximum_move_distance - (config.maximum_move_distance_slow + extra_slow_speed);
|
||||||
offset_fast = safe_offset_inc(offset_slow, delta_slow_fast, wall_restriction, safe_movement_distance, safe_movement_distance + radius, offset_independant_faster ? 2 : 1);
|
offset_fast = safe_offset_inc(offset_slow, delta_slow_fast, wall_restriction, safe_movement_distance, safe_movement_distance + radius, offset_independant_faster ? 2 : 1);
|
||||||
}
|
}
|
||||||
#ifdef TREESUPPORT_DEBUG_SVG
|
|
||||||
SVG::export_expolygons(debug_out_path("treesupport-increase_areas_one_layer-fast-%d-%ld.svg", layer_idx, int(merging_area_idx)),
|
|
||||||
{ { { union_ex(wall_restriction) }, { "wall_restricrictions", "gray", 0.5f } },
|
|
||||||
{ { union_ex(offset_fast) }, { "offset_fast", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
|
||||||
#endif // TREESUPPORT_DEBUG_SVG
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::optional<SupportElementState> result;
|
std::optional<SupportElementState> result;
|
||||||
@@ -3486,18 +3460,6 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
|||||||
move_bounds, interface_placer, throw_on_cancel);
|
move_bounds, interface_placer, throw_on_cancel);
|
||||||
auto t_gen = std::chrono::high_resolution_clock::now();
|
auto t_gen = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
#ifdef TREESUPPORT_DEBUG_SVG
|
|
||||||
for (size_t layer_idx = 0; layer_idx < move_bounds.size(); ++layer_idx) {
|
|
||||||
Polygons polys;
|
|
||||||
for (auto& area : move_bounds[layer_idx])
|
|
||||||
append(polys, area.influence_area);
|
|
||||||
if (auto begin = move_bounds[layer_idx].begin(); begin != move_bounds[layer_idx].end())
|
|
||||||
SVG::export_expolygons(debug_out_path("treesupport-initial_areas-%d.svg", layer_idx),
|
|
||||||
{ { { union_ex(volumes.getWallRestriction(support_element_collision_radius(config, begin->state), layer_idx, begin->state.use_min_xy_dist)) },
|
|
||||||
{ "wall_restricrictions", "gray", 0.5f } },
|
|
||||||
{ { union_ex(polys) }, { "parent", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
|
|
||||||
}
|
|
||||||
#endif // TREESUPPORT_DEBUG_SVG
|
|
||||||
|
|
||||||
// ### Propagate the influence areas downwards. This is an inherently serial operation.
|
// ### Propagate the influence areas downwards. This is an inherently serial operation.
|
||||||
print.set_status(60, _L("Generating support"));
|
print.set_status(60, _L("Generating support"));
|
||||||
@@ -3829,23 +3791,65 @@ void organic_draw_branches(
|
|||||||
const double bottom_z = layer_idx > 0 ? layer_z(slicing_params, config, layer_idx - 1) : 0.;
|
const double bottom_z = layer_idx > 0 ? layer_z(slicing_params, config, layer_idx - 1) : 0.;
|
||||||
slice_z.emplace_back(float(0.5 * (bottom_z + print_z)));
|
slice_z.emplace_back(float(0.5 * (bottom_z + print_z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Polygons> slices = slice_mesh(partial_mesh, slice_z, mesh_slicing_params, throw_on_cancel);
|
std::vector<Polygons> slices = slice_mesh(partial_mesh, slice_z, mesh_slicing_params, throw_on_cancel);
|
||||||
|
|
||||||
|
// ORCA: guard against empty slices from meshing.
|
||||||
|
if (slices.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
bottom_contacts.clear();
|
bottom_contacts.clear();
|
||||||
|
// ORCA: trim tiny fragments to reduce degenerate polygon booleans.
|
||||||
|
const double tiny_area = tiny_area_threshold();
|
||||||
//FIXME parallelize?
|
//FIXME parallelize?
|
||||||
for (LayerIndex i = 0; i < LayerIndex(slices.size()); ++i) {
|
for (LayerIndex i = 0; i < LayerIndex(slices.size()); ++i) {
|
||||||
slices[i] = diff_clipped(slices[i], volumes.getCollision(0, layer_begin + i, true)); // FIXME parent_uses_min || draw_area.element->state.use_min_xy_dist);
|
// ORCA: safety offset when trimming collision/bed to improve robustness.
|
||||||
slices[i] = intersection(slices[i], volumes.m_bed_area);
|
slices[i] = diff_clipped(slices[i], volumes.getCollision(0, layer_begin + i, true), ApplySafetyOffset::Yes); // FIXME parent_uses_min || draw_area.element->state.use_min_xy_dist);
|
||||||
|
slices[i] = intersection(slices[i], volumes.m_bed_area, ApplySafetyOffset::Yes);
|
||||||
|
remove_small(slices[i], tiny_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_empty = 0;
|
size_t num_empty = 0;
|
||||||
|
|
||||||
if (slices.front().empty()) {
|
if (slices.front().empty()) {
|
||||||
// Some of the initial layers are empty.
|
// Some of the initial layers are empty.
|
||||||
num_empty = std::find_if(slices.begin(), slices.end(), [](auto &s) { return !s.empty(); }) - slices.begin();
|
num_empty = std::find_if(slices.begin(), slices.end(), [](auto &s) { return !s.empty(); }) - slices.begin();
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// ORCA: trim leading empty slices to keep layer indices aligned.
|
||||||
|
if (num_empty >= slices.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (num_empty > 0) {
|
||||||
|
slices.erase(slices.begin(), slices.begin() + num_empty);
|
||||||
|
layer_begin += LayerIndex(num_empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ORCA: use the trimmed front slice as the contact reference.
|
||||||
|
Polygons slice_front_contact = slices.front();
|
||||||
|
|
||||||
if (branch.has_root) {
|
if (branch.has_root) {
|
||||||
if (config.support_rests_on_model && branch.path.front()->state.to_model_gracious) {
|
if (branch.path.front()->state.to_model_gracious) {
|
||||||
if (config.settings.support_floor_layers > 0)
|
if (config.settings.support_floor_layers > 0) {
|
||||||
//FIXME one may just take the whole tree slice as bottom interface.
|
// If bottom Z gap is non-zero, keep bottom contacts even when not touching the model.
|
||||||
bottom_contacts.emplace_back(intersection_clipped(slices.front(), volumes.getPlaceableAreas(0, layer_begin, [] {})));
|
Polygons contacts;
|
||||||
|
|
||||||
|
// ORCA: non-zero bottom Z should not be clipped by placeable areas.
|
||||||
|
if (config.support_rests_on_model && config.z_distance_bottom_layers > 0 && layer_begin > 0)
|
||||||
|
contacts = slice_front_contact;
|
||||||
|
else {
|
||||||
|
Polygons placeable = volumes.getPlaceableAreas(0, layer_begin, [] {});
|
||||||
|
contacts = intersection_clipped(slice_front_contact, placeable, ApplySafetyOffset::Yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_small(contacts, tiny_area);
|
||||||
|
|
||||||
|
// ORCA: ensure bottom contacts exist if clipping removed them.
|
||||||
|
if (contacts.empty() && config.support_rests_on_model && layer_begin > 0 && !slice_front_contact.empty())
|
||||||
|
contacts = slice_front_contact;
|
||||||
|
if (!contacts.empty())
|
||||||
|
bottom_contacts.emplace_back(std::move(contacts));
|
||||||
|
}
|
||||||
} else if (layer_begin > 0) {
|
} else if (layer_begin > 0) {
|
||||||
// Drop down areas that do rest non - gracefully on the model to ensure the branch actually rests on something.
|
// Drop down areas that do rest non - gracefully on the model to ensure the branch actually rests on something.
|
||||||
struct BottomExtraSlice {
|
struct BottomExtraSlice {
|
||||||
@@ -3868,7 +3872,10 @@ void organic_draw_branches(
|
|||||||
// Only propagate until the rest area is smaller than this threshold.
|
// Only propagate until the rest area is smaller than this threshold.
|
||||||
//double support_area_min = 0.1 * support_area_min_radius;
|
//double support_area_min = 0.1 * support_area_min_radius;
|
||||||
for (LayerIndex layer_idx = layer_begin - 1; layer_idx >= layer_bottommost; -- layer_idx) {
|
for (LayerIndex layer_idx = layer_begin - 1; layer_idx >= layer_bottommost; -- layer_idx) {
|
||||||
rest_support = diff_clipped(rest_support.empty() ? slices.front() : rest_support, volumes.getCollision(0, layer_idx, false));
|
LayerIndex collision_layer = (layer_idx == layer_begin - 1) ? layer_begin : layer_idx;
|
||||||
|
Polygons collision = volumes.getCollision(0, collision_layer, false);
|
||||||
|
rest_support = diff_clipped(rest_support.empty() ? slice_front_contact : rest_support, collision, ApplySafetyOffset::Yes);
|
||||||
|
remove_small(rest_support, tiny_area);
|
||||||
double rest_support_area = area(rest_support);
|
double rest_support_area = area(rest_support);
|
||||||
if (rest_support_area < support_area_stop)
|
if (rest_support_area < support_area_stop)
|
||||||
// Don't propagate a fraction of the tree contact surface.
|
// Don't propagate a fraction of the tree contact surface.
|
||||||
@@ -3891,26 +3898,74 @@ void organic_draw_branches(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (config.support_rests_on_model && config.settings.support_floor_layers > 0)
|
if (config.settings.support_floor_layers > 0) {
|
||||||
for (int i = int(bottom_extra_slices.size()) - 2; i >= 0; -- i)
|
Polygons contacts;
|
||||||
bottom_contacts.emplace_back(
|
if (!bottom_extra_slices.empty()) {
|
||||||
intersection_clipped(bottom_extra_slices[i].polygons, volumes.getPlaceableAreas(0, layer_begin - i - 1, [] {})));
|
const int contact_idx = int(bottom_extra_slices.size()) - 1; // Use the lowest contact slice as the footprint.
|
||||||
|
|
||||||
|
// ORCA: non-zero bottom Z should not be clipped by placeable areas.
|
||||||
|
if (config.support_rests_on_model && config.z_distance_bottom_layers > 0 && layer_begin > 0)
|
||||||
|
contacts = intersection_clipped(bottom_extra_slices[contact_idx].polygons, Polygons{volumes.m_bed_area}, ApplySafetyOffset::Yes);
|
||||||
|
else {
|
||||||
|
Polygons placeable = volumes.getPlaceableAreas(0, layer_begin, [] {});
|
||||||
|
contacts = intersection_clipped(bottom_extra_slices[contact_idx].polygons, placeable, ApplySafetyOffset::Yes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback: use the current contact slice when no propagation happened.
|
||||||
|
if (config.support_rests_on_model && config.z_distance_bottom_layers > 0 && layer_begin > 0)
|
||||||
|
contacts = slice_front_contact;
|
||||||
|
else {
|
||||||
|
Polygons placeable = volumes.getPlaceableAreas(0, layer_begin, [] {});
|
||||||
|
contacts = intersection_clipped(slice_front_contact, placeable, ApplySafetyOffset::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_small(contacts, tiny_area);
|
||||||
|
|
||||||
|
if (!contacts.empty())
|
||||||
|
bottom_contacts.emplace_back(std::move(contacts));
|
||||||
|
|
||||||
|
// ORCA: ensure bottom contacts exist if clipping removed them.
|
||||||
|
if (bottom_contacts.empty() && config.support_rests_on_model && layer_begin > 0 && !slice_front_contact.empty())
|
||||||
|
bottom_contacts.emplace_back(slice_front_contact);
|
||||||
|
}
|
||||||
layer_begin -= LayerIndex(bottom_extra_slices.size());
|
layer_begin -= LayerIndex(bottom_extra_slices.size());
|
||||||
slices.insert(slices.begin(), bottom_extra_slices.size(), {});
|
slices.insert(slices.begin(), bottom_extra_slices.size(), {});
|
||||||
auto it_dst = slices.begin();
|
auto it_dst = slices.begin();
|
||||||
for (auto it_src = bottom_extra_slices.rbegin(); it_src != bottom_extra_slices.rend(); ++ it_src)
|
for (auto it_src = bottom_extra_slices.rbegin(); it_src != bottom_extra_slices.rend(); ++ it_src)
|
||||||
*it_dst ++ = std::move(it_src->polygons);
|
*it_dst ++ = std::move(it_src->polygons);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
recover_pending_branch_roofs(interface_placer, branch.path, layer_begin, slices);
|
// ORCA: retain bottom contacts even when no placeable areas intersect.
|
||||||
|
if (branch.has_root && config.support_rests_on_model && branch.path.front()->state.layer_idx > 0 &&
|
||||||
|
config.settings.support_floor_layers > 0 && config.z_distance_bottom_layers > 0 &&
|
||||||
|
bottom_contacts.empty() && !slice_front_contact.empty())
|
||||||
|
bottom_contacts.emplace_back(slice_front_contact);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// ORCA: bottom contacts provide the footprint; interface layers are built later.
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//FIXME branch.has_tip seems to not be reliable.
|
||||||
|
if (branch.has_tip && interface_placer.support_parameters.has_top_contacts)
|
||||||
|
// Add top slices to top contacts / interfaces / base interfaces.
|
||||||
|
for (int i = int(branch.path.size()) - 1; i >= 0; -- i) {
|
||||||
|
const SupportElement &el = *branch.path[i];
|
||||||
|
if (el.state.missing_roof_layers == 0)
|
||||||
|
break;
|
||||||
|
//FIXME Move or not?
|
||||||
|
interface_placer.add_roof(std::move(slices[int(slices.size()) - i - 1]), el.state.layer_idx,
|
||||||
|
interface_placer.support_parameters.num_top_interface_layers + 1 - el.state.missing_roof_layers);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
layer_begin += LayerIndex(num_empty);
|
|
||||||
while (! slices.empty() && slices.back().empty()) {
|
while (! slices.empty() && slices.back().empty()) {
|
||||||
slices.pop_back();
|
slices.pop_back();
|
||||||
-- layer_end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ORCA: recompute layer_end after trimming trailing empty slices.
|
||||||
|
layer_end = layer_begin + LayerIndex(slices.size());
|
||||||
|
|
||||||
if (layer_begin < layer_end) {
|
if (layer_begin < layer_end) {
|
||||||
LayerIndex new_begin = tree.first_layer_id == -1 ? layer_begin : std::min(tree.first_layer_id, layer_begin);
|
LayerIndex new_begin = tree.first_layer_id == -1 ? layer_begin : std::min(tree.first_layer_id, layer_begin);
|
||||||
LayerIndex new_end = tree.first_layer_id == -1 ? layer_end : std::max(tree.first_layer_id + LayerIndex(tree.slices.size()), layer_end);
|
LayerIndex new_end = tree.first_layer_id == -1 ? layer_end : std::max(tree.first_layer_id + LayerIndex(tree.slices.size()), layer_end);
|
||||||
@@ -3926,22 +3981,28 @@ void organic_draw_branches(
|
|||||||
} else if (LayerIndex dif = tree.first_layer_id - new_begin; dif > 0)
|
} else if (LayerIndex dif = tree.first_layer_id - new_begin; dif > 0)
|
||||||
tree.slices.insert(tree.slices.begin(), tree.first_layer_id - new_begin, {});
|
tree.slices.insert(tree.slices.begin(), tree.first_layer_id - new_begin, {});
|
||||||
tree.slices.insert(tree.slices.end(), new_size - tree.slices.size(), {});
|
tree.slices.insert(tree.slices.end(), new_size - tree.slices.size(), {});
|
||||||
layer_begin -= LayerIndex(num_empty);
|
|
||||||
for (LayerIndex i = layer_begin; i != layer_end; ++ i) {
|
for (LayerIndex i = layer_begin; i != layer_end; ++ i) {
|
||||||
int j = i - layer_begin;
|
int j = i - layer_begin;
|
||||||
if (Polygons &src = slices[j]; ! src.empty()) {
|
Polygons &src = slices[j];
|
||||||
|
bool has_bottom_contacts = j < int(bottom_contacts.size()) && !bottom_contacts[j].empty();
|
||||||
|
|
||||||
|
// ORCA: preserve bottom contacts even if base polygons are empty.
|
||||||
|
if (!src.empty() || has_bottom_contacts) {
|
||||||
Slice &dst = tree.slices[i - new_begin];
|
Slice &dst = tree.slices[i - new_begin];
|
||||||
if (++ dst.num_branches > 1) {
|
if (++ dst.num_branches > 1) {
|
||||||
|
if (!src.empty())
|
||||||
append(dst.polygons, std::move(src));
|
append(dst.polygons, std::move(src));
|
||||||
if (j < int(bottom_contacts.size()))
|
if (has_bottom_contacts)
|
||||||
append(dst.bottom_contacts, std::move(bottom_contacts[j]));
|
append(dst.bottom_contacts, std::move(bottom_contacts[j]));
|
||||||
} else {
|
} else {
|
||||||
dst.polygons = std::move(std::move(src));
|
if (!src.empty())
|
||||||
if (j < int(bottom_contacts.size()))
|
dst.polygons = std::move(src);
|
||||||
|
if (has_bottom_contacts)
|
||||||
dst.bottom_contacts = std::move(bottom_contacts[j]);
|
dst.bottom_contacts = std::move(bottom_contacts[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.first_layer_id = new_begin;
|
tree.first_layer_id = new_begin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3954,10 +4015,15 @@ void organic_draw_branches(
|
|||||||
Tree &tree = trees[tree_id];
|
Tree &tree = trees[tree_id];
|
||||||
for (Slice &slice : tree.slices)
|
for (Slice &slice : tree.slices)
|
||||||
if (slice.num_branches > 1) {
|
if (slice.num_branches > 1) {
|
||||||
|
// ORCA: avoid union_ on empty containers.
|
||||||
|
if (!slice.polygons.empty())
|
||||||
slice.polygons = union_(slice.polygons);
|
slice.polygons = union_(slice.polygons);
|
||||||
|
if (!slice.bottom_contacts.empty())
|
||||||
slice.bottom_contacts = union_(slice.bottom_contacts);
|
slice.bottom_contacts = union_(slice.bottom_contacts);
|
||||||
|
|
||||||
slice.num_branches = 1;
|
slice.num_branches = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
}
|
}
|
||||||
}, tbb::simple_partitioner());
|
}, tbb::simple_partitioner());
|
||||||
@@ -3970,26 +4036,39 @@ void organic_draw_branches(
|
|||||||
std::vector<Slice> slices(num_layers, Slice{});
|
std::vector<Slice> slices(num_layers, Slice{});
|
||||||
for (Tree &tree : trees)
|
for (Tree &tree : trees)
|
||||||
if (tree.first_layer_id >= 0) {
|
if (tree.first_layer_id >= 0) {
|
||||||
for (LayerIndex i = tree.first_layer_id; i != tree.first_layer_id + LayerIndex(tree.slices.size()); ++ i)
|
for (LayerIndex i = tree.first_layer_id; i != tree.first_layer_id + LayerIndex(tree.slices.size()); ++ i) {
|
||||||
if (Slice &src = tree.slices[i - tree.first_layer_id]; ! src.polygons.empty()) {
|
Slice &src = tree.slices[i - tree.first_layer_id];
|
||||||
|
bool has_bottom_contacts = !src.bottom_contacts.empty();
|
||||||
|
|
||||||
|
// ORCA: preserve bottom contacts even if base polygons are empty.
|
||||||
|
if (!src.polygons.empty() || has_bottom_contacts) {
|
||||||
Slice &dst = slices[i];
|
Slice &dst = slices[i];
|
||||||
|
|
||||||
if (++ dst.num_branches > 1) {
|
if (++ dst.num_branches > 1) {
|
||||||
|
if (!src.polygons.empty())
|
||||||
append(dst.polygons, std::move(src.polygons));
|
append(dst.polygons, std::move(src.polygons));
|
||||||
|
if (has_bottom_contacts)
|
||||||
append(dst.bottom_contacts, std::move(src.bottom_contacts));
|
append(dst.bottom_contacts, std::move(src.bottom_contacts));
|
||||||
} else {
|
} else {
|
||||||
|
if (!src.polygons.empty())
|
||||||
dst.polygons = std::move(src.polygons);
|
dst.polygons = std::move(src.polygons);
|
||||||
|
if (has_bottom_contacts)
|
||||||
dst.bottom_contacts = std::move(src.bottom_contacts);
|
dst.bottom_contacts = std::move(src.bottom_contacts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, std::min(move_bounds.size(), slices.size()), 1),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, std::min(move_bounds.size(), slices.size()), 1),
|
||||||
[&print_object, &config, &slices, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_storage, &throw_on_cancel](const tbb::blocked_range<size_t> &range) {
|
[&print_object, &config, &slices, &bottom_contacts, &top_contacts, &intermediate_layers, &layer_storage, &throw_on_cancel](const tbb::blocked_range<size_t> &range) {
|
||||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||||
Slice &slice = slices[layer_idx];
|
Slice &slice = slices[layer_idx];
|
||||||
assert(intermediate_layers[layer_idx] == nullptr);
|
assert(intermediate_layers[layer_idx] == nullptr);
|
||||||
Polygons base_layer_polygons = slice.num_branches > 1 ? union_(slice.polygons) : std::move(slice.polygons);
|
// ORCA: avoid union_ on empty inputs.
|
||||||
Polygons bottom_contact_polygons = slice.num_branches > 1 ? union_(slice.bottom_contacts) : std::move(slice.bottom_contacts);
|
Polygons base_layer_polygons = slice.polygons.empty() ? Polygons{} :
|
||||||
|
(slice.num_branches > 1 ? union_(slice.polygons) : std::move(slice.polygons));
|
||||||
|
Polygons bottom_contact_polygons = slice.bottom_contacts.empty() ? Polygons{} :
|
||||||
|
(slice.num_branches > 1 ? union_(slice.bottom_contacts) : std::move(slice.bottom_contacts));
|
||||||
|
|
||||||
if (! base_layer_polygons.empty()) {
|
if (! base_layer_polygons.empty()) {
|
||||||
// Most of the time in this function is this union call. Can take 300+ ms when a lot of areas are to be unioned.
|
// Most of the time in this function is this union call. Can take 300+ ms when a lot of areas are to be unioned.
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ public:
|
|||||||
|
|
||||||
layer_start_bp_radius = (bp_radius - branch_radius) / bp_radius_increase_per_layer;
|
layer_start_bp_radius = (bp_radius - branch_radius) / bp_radius_increase_per_layer;
|
||||||
|
|
||||||
if (TreeSupportSettings::soluble) {
|
if (TreeSupportSettings::zero_top_z_gap) {
|
||||||
// safeOffsetInc can only work in steps of the size xy_min_distance in the worst case => xy_min_distance has to be a bit larger than 0 in this worst case and should be large enough for performance to not suffer extremely
|
// safeOffsetInc can only work in steps of the size xy_min_distance in the worst case => xy_min_distance has to be a bit larger than 0 in this worst case and should be large enough for performance to not suffer extremely
|
||||||
// When for all meshes the z bottom and top distance is more than one layer though the worst case is xy_min_distance + min_feature_size
|
// When for all meshes the z bottom and top distance is more than one layer though the worst case is xy_min_distance + min_feature_size
|
||||||
// This is not the best solution, but the only one to ensure areas can not lag though walls at high maximum_move_distance.
|
// This is not the best solution, but the only one to ensure areas can not lag though walls at high maximum_move_distance.
|
||||||
@@ -356,7 +356,7 @@ public:
|
|||||||
|
|
||||||
// some static variables dependent on other meshes that are not currently processed.
|
// some static variables dependent on other meshes that are not currently processed.
|
||||||
// Has to be static because TreeSupportConfig will be used in TreeModelVolumes as this reduces redundancy.
|
// Has to be static because TreeSupportConfig will be used in TreeModelVolumes as this reduces redundancy.
|
||||||
inline static bool soluble = false;
|
inline static bool zero_top_z_gap = false;
|
||||||
/*!
|
/*!
|
||||||
* \brief Width of a single line of support.
|
* \brief Width of a single line of support.
|
||||||
*/
|
*/
|
||||||
@@ -718,9 +718,15 @@ public:
|
|||||||
{
|
{
|
||||||
assert(support_parameters.has_top_contacts);
|
assert(support_parameters.has_top_contacts);
|
||||||
assert(dtt_roof <= support_parameters.num_top_interface_layers);
|
assert(dtt_roof <= support_parameters.num_top_interface_layers);
|
||||||
|
// ORCA: Reserve one top interface layer but only when top base-interface layers exist.
|
||||||
|
// This prevents all interface layers from being classified as base-interface layers
|
||||||
|
// and preserves correct top contact and interface behavior.
|
||||||
|
size_t interface_threshold = support_parameters.num_top_interface_layers_only();
|
||||||
|
if (interface_threshold > 0 && support_parameters.num_top_base_interface_layers > 0)
|
||||||
|
--interface_threshold;
|
||||||
SupportGeneratorLayersPtr &layers =
|
SupportGeneratorLayersPtr &layers =
|
||||||
dtt_roof == 0 ? this->top_contacts :
|
dtt_roof == 0 ? this->top_contacts :
|
||||||
dtt_roof <= support_parameters.num_top_interface_layers_only() ? this->top_interfaces : this->top_base_interfaces;
|
dtt_roof <= interface_threshold ? this->top_interfaces : this->top_base_interfaces;
|
||||||
SupportGeneratorLayer*& l = layers[insert_layer_idx];
|
SupportGeneratorLayer*& l = layers[insert_layer_idx];
|
||||||
if (l == nullptr)
|
if (l == nullptr)
|
||||||
l = &layer_allocate_unguarded(layer_storage, dtt_roof == 0 ? SupporLayerType::TopContact : SupporLayerType::TopInterface,
|
l = &layer_allocate_unguarded(layer_storage, dtt_roof == 0 ? SupporLayerType::TopContact : SupporLayerType::TopInterface,
|
||||||
|
|||||||
Reference in New Issue
Block a user