mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-20 14:08:20 +00:00
Compare commits
85
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4afd257371 | ||
|
|
4a0d5e5edd | ||
|
|
069bd402d9 | ||
|
|
6626377abc | ||
|
|
74d4392dae | ||
|
|
0d5b3a79d7 | ||
|
|
c9d897b4d0 | ||
|
|
6bff3c3cd6 | ||
|
|
6e1d15f8a2 | ||
|
|
4f63cd4051 | ||
|
|
c7489d431d | ||
|
|
506dd497db | ||
|
|
56da2f43b0 | ||
|
|
00838d59c1 | ||
|
|
8f8bfd6a28 | ||
|
|
90a5a0b964 | ||
|
|
f64beb4379 | ||
|
|
a2b1a2f3e7 | ||
|
|
0585836550 | ||
|
|
5a36120c58 | ||
|
|
69193d5681 | ||
|
|
6c791532c6 | ||
|
|
cdb9bb57ae | ||
|
|
f0c59208e7 | ||
|
|
9f6a344162 | ||
|
|
c5cfe40a1f | ||
|
|
e5b6cbf091 | ||
|
|
3b9b871ba6 | ||
|
|
cb2260f057 | ||
|
|
3fcbb2adf9 | ||
|
|
252bbbf9f5 | ||
|
|
4c2ae6d202 | ||
|
|
ac022b56ad | ||
|
|
d3699dd9f6 | ||
|
|
a315a96c5c | ||
|
|
24cf1c6bcc | ||
|
|
d16ca97380 | ||
|
|
da4d766d46 | ||
|
|
06665d0558 | ||
|
|
0f59cd5d05 | ||
|
|
c1fb801ff3 | ||
|
|
1ee0b730a1 | ||
|
|
72ba7a2b35 | ||
|
|
8160f64cae | ||
|
|
fd28f6c189 | ||
|
|
9b2fcaa53a | ||
|
|
0acf1e6680 | ||
|
|
c6804fbb68 | ||
|
|
6d40ec93f6 | ||
|
|
82aee1abdd | ||
|
|
cefdd9b609 | ||
|
|
caade80624 | ||
|
|
cbd8ce98d5 | ||
|
|
99714afc4c | ||
|
|
3d07663ab2 | ||
|
|
29b6bbb8c9 | ||
|
|
8b6c074c69 | ||
|
|
109d09e0b8 | ||
|
|
b00237807d | ||
|
|
4149401c53 | ||
|
|
f6cf18fb96 | ||
|
|
4ee1b9c6e9 | ||
|
|
bc8d0a7858 | ||
|
|
e0651ec31d | ||
|
|
0caefcf4aa | ||
|
|
86905a8a20 | ||
|
|
d4fabbf7c8 | ||
|
|
51efb24752 | ||
|
|
cf9ec18df5 | ||
|
|
99de46b9d0 | ||
|
|
258f927a0f | ||
|
|
b8d40ed61f | ||
|
|
6aa613ccf0 | ||
|
|
54e6df0235 | ||
|
|
7599868797 | ||
|
|
81ec931990 | ||
|
|
8fd97b5120 | ||
|
|
aacc36b9d2 | ||
|
|
79ed246d26 | ||
|
|
92b5301bf6 | ||
|
|
20c157b0f4 | ||
|
|
4cf16febf6 | ||
|
|
70e52a105f | ||
|
|
b525cb79e1 | ||
|
|
86ab598899 |
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: orca-translations
|
name: orca-translations
|
||||||
description: Use when updating, filling, reviewing or fixing OrcaSlicer translations in localization/i18n — running scripts/run_gettext --full, translating empty or new msgids in the .po catalogs, AI translation passes and their "# AI Translated" / "# Needs human review" comments, plural forms, msgctxt homonyms, and keeping catalogs consistent with the localization glossary (OrcaSlicer_WIKI localization_glossary.tsv), including adding new glossary terms. Also use for msgfmt or run_gettext failures, placeholder or line-break mismatches, and reviewing a translation PR against the glossary.
|
description: Use when updating, filling, reviewing or fixing OrcaSlicer translations in localization/i18n — running scripts/run_gettext --full, translating empty or new msgids in the .po catalogs, AI translation passes and their "# AI Translated" / "# Needs human review" comments, plural forms, msgctxt homonyms, and keeping catalogs consistent with the localization glossary (OrcaSlicer_WIKI developer_reference/glossary), including adding new glossary terms. Also use for msgfmt or run_gettext failures, placeholder or line-break mismatches, and reviewing a translation PR against the glossary.
|
||||||
---
|
---
|
||||||
|
|
||||||
# OrcaSlicer translations
|
# OrcaSlicer translations
|
||||||
@@ -9,7 +9,7 @@ The UI strings live in gettext catalogs: `localization/i18n/OrcaSlicer.pot` is t
|
|||||||
`localization/i18n/<lang>/OrcaSlicer_<lang>.po` holds each language. The `en` catalog is empty on
|
`localization/i18n/<lang>/OrcaSlicer_<lang>.po` holds each language. The `en` catalog is empty on
|
||||||
purpose, so skip it. Recurring terms are fixed by the
|
purpose, so skip it. Recurring terms are fixed by the
|
||||||
[localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md),
|
[localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md),
|
||||||
whose source is `developer_reference/localization_glossary.tsv` in the **OrcaSlicer_WIKI** repository.
|
whose source is the per-language files in `developer_reference/glossary/` (`terms.tsv`, `languages.txt` and one `<lang>.tsv`) in the **OrcaSlicer_WIKI** repository.
|
||||||
A translation pass therefore touches two repositories: the catalogs here, and the glossary there.
|
A translation pass therefore touches two repositories: the catalogs here, and the glossary there.
|
||||||
|
|
||||||
All catalog editing goes through [`scripts/po_tool.py`](scripts/po_tool.py) (standard library only).
|
All catalog editing goes through [`scripts/po_tool.py`](scripts/po_tool.py) (standard library only).
|
||||||
@@ -153,7 +153,7 @@ Report:
|
|||||||
- anything left empty, and why;
|
- anything left empty, and why;
|
||||||
- the glossary rows added or filled.
|
- the glossary rows added or filled.
|
||||||
|
|
||||||
The catalogs (and `OrcaSlicer.pot`) and the glossary (`localization_glossary.tsv` and `.md`) are
|
The catalogs (and `OrcaSlicer.pot`) and the glossary (`developer_reference/glossary/*.tsv` and `localization_glossary.md`) are
|
||||||
separate changes in separate repositories. The wiki change should land with, or before, the catalog
|
separate changes in separate repositories. The wiki change should land with, or before, the catalog
|
||||||
change. Commit or open PRs only when asked.
|
change. Commit or open PRs only when asked.
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ with the translators, followed by the catalogs.
|
|||||||
When this skill and the checkouts disagree, the checkouts win:
|
When this skill and the checkouts disagree, the checkouts win:
|
||||||
- `scripts/run_gettext.sh` / `.bat` for extraction and merging;
|
- `scripts/run_gettext.sh` / `.bat` for extraction and merging;
|
||||||
- `localization/i18n/list.txt` for the scanned sources;
|
- `localization/i18n/list.txt` for the scanned sources;
|
||||||
- the wiki's `localization_guide.md` and `localization_glossary.md` / `.tsv` for the rules and terms;
|
- the wiki's `localization_guide.md` and `localization_glossary.md` and `glossary/*.tsv` for the rules and terms;
|
||||||
- `AGENTS.md` (Localization & translations) for the repository's conventions.
|
- `AGENTS.md` (Localization & translations) for the repository's conventions.
|
||||||
|
|
||||||
## Editing this skill
|
## Editing this skill
|
||||||
|
|||||||
@@ -28,13 +28,14 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
import urllib.error
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
REPO = Path(__file__).resolve().parents[4]
|
REPO = Path(__file__).resolve().parents[4]
|
||||||
I18N = REPO / "localization" / "i18n"
|
I18N = REPO / "localization" / "i18n"
|
||||||
SKIP_LANGS = {"en"} # the English catalog is intentionally empty
|
SKIP_LANGS = {"en"} # the English catalog is intentionally empty
|
||||||
GLOSSARY_TSV = Path("developer_reference") / "localization_glossary.tsv"
|
GLOSSARY_DIR = Path("developer_reference") / "glossary" # terms.tsv, languages.txt and one <lang>.tsv per language
|
||||||
GLOSSARY_MD = Path("developer_reference") / "localization_glossary.md"
|
GLOSSARY_MD = Path("developer_reference") / "localization_glossary.md"
|
||||||
MISSING = {"", "—"}
|
MISSING = {"", "—"}
|
||||||
RAW_URL = "https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer_WIKI/main/"
|
RAW_URL = "https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer_WIKI/main/"
|
||||||
@@ -252,30 +253,40 @@ def all_langs():
|
|||||||
|
|
||||||
def find_wiki(arg):
|
def find_wiki(arg):
|
||||||
for cand in [arg, os.environ.get("ORCA_WIKI_DIR"), REPO.parent / "OrcaSlicer_WIKI", REPO.parent / "OrcaSlicer.wiki"]:
|
for cand in [arg, os.environ.get("ORCA_WIKI_DIR"), REPO.parent / "OrcaSlicer_WIKI", REPO.parent / "OrcaSlicer.wiki"]:
|
||||||
if cand and (Path(cand) / GLOSSARY_TSV).exists():
|
if cand and (Path(cand) / GLOSSARY_DIR / "terms.tsv").exists():
|
||||||
return Path(cand)
|
return Path(cand)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _download(rel):
|
def _download(rel, required=True):
|
||||||
cache = Path(tempfile.gettempdir()) / ("orca_glossary_" + rel.name)
|
cache = Path(tempfile.gettempdir()) / "orca_glossary" / rel
|
||||||
if not cache.exists() or time.time() - cache.stat().st_mtime > 3600:
|
if not cache.exists() or time.time() - cache.stat().st_mtime > 3600:
|
||||||
with urllib.request.urlopen(RAW_URL + rel.as_posix(), timeout=30) as r:
|
try:
|
||||||
cache.write_bytes(r.read())
|
with urllib.request.urlopen(RAW_URL + rel.as_posix(), timeout=30) as r:
|
||||||
|
data = r.read()
|
||||||
|
except urllib.error.HTTPError:
|
||||||
|
if required:
|
||||||
|
raise
|
||||||
|
return None
|
||||||
|
cache.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
cache.write_bytes(data)
|
||||||
return cache
|
return cache
|
||||||
|
|
||||||
|
|
||||||
class Glossary:
|
class Glossary:
|
||||||
def __init__(self, wiki_arg=None, quiet=False):
|
"""The glossary: rows of [English, Description, <one translation per language loaded>]."""
|
||||||
|
|
||||||
|
def __init__(self, wiki_arg=None, quiet=False, langs=None):
|
||||||
self.wiki = find_wiki(wiki_arg)
|
self.wiki = find_wiki(wiki_arg)
|
||||||
|
self.langs = langs # only these languages' files are read (and downloaded); None means all
|
||||||
if self.wiki:
|
if self.wiki:
|
||||||
self.tsv, self.md = self.wiki / GLOSSARY_TSV, self.wiki / GLOSSARY_MD
|
self.dir, self.md = self.wiki / GLOSSARY_DIR, self.wiki / GLOSSARY_MD
|
||||||
if not quiet:
|
if not quiet:
|
||||||
self.report_clone_state()
|
self.report_clone_state()
|
||||||
else:
|
else:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print("note: no OrcaSlicer_WIKI clone found; using the published glossary read-only", file=sys.stderr)
|
print("note: no OrcaSlicer_WIKI clone found; using the published glossary read-only", file=sys.stderr)
|
||||||
self.tsv, self.md = _download(GLOSSARY_TSV), _download(GLOSSARY_MD)
|
self.dir, self.md = _download(GLOSSARY_DIR / "terms.tsv").parent, _download(GLOSSARY_MD)
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
def report_clone_state(self):
|
def report_clone_state(self):
|
||||||
@@ -290,11 +301,23 @@ class Glossary:
|
|||||||
if behind and behind != "0":
|
if behind and behind != "0":
|
||||||
print(f"note: the wiki clone is {behind} commits behind origin/main (as of its last fetch)", file=sys.stderr)
|
print(f"note: the wiki clone is {behind} commits behind origin/main (as of its last fetch)", file=sys.stderr)
|
||||||
|
|
||||||
|
def _read(self, name, required=True):
|
||||||
|
path = self.dir / name if self.wiki else _download(GLOSSARY_DIR / name, required)
|
||||||
|
return path.read_text(encoding="utf-8-sig").splitlines() if path and path.exists() else None
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
rows = [l.split("\t") for l in self.tsv.read_text(encoding="utf-8-sig").splitlines() if l.strip()]
|
terms = [l.split(" ") for l in self._read("terms.tsv")[1:] if l.strip()]
|
||||||
self.header = rows[0]
|
langs = [l.strip() for l in self._read("languages.txt") if l.strip()]
|
||||||
# "—" marks a language with no established rendering yet
|
langs = [l for l in langs if self.langs is None or l in self.langs]
|
||||||
self.rows = [[c if c.strip() not in MISSING else "" for c in r] + [""] * (len(rows[0]) - len(r)) for r in rows[1:]]
|
self.header = ["English", "Description"] + langs
|
||||||
|
self.rows = [[r[0], r[1] if len(r) > 1 else ""] + [""] * len(langs) for r in terms]
|
||||||
|
index = {r[0]: r for r in self.rows}
|
||||||
|
for col, lang in enumerate(langs, start=2):
|
||||||
|
for line in (self._read(f"{lang}.tsv", required=False) or [])[1:]:
|
||||||
|
cells = line.split(" ")
|
||||||
|
# "—" marks a language with no established rendering yet
|
||||||
|
if len(cells) > 2 and cells[0] in index and cells[2].strip() not in MISSING:
|
||||||
|
index[cells[0]][col] = cells[2].strip()
|
||||||
self.matchers = []
|
self.matchers = []
|
||||||
for row in self.rows:
|
for row in self.rows:
|
||||||
base = re.sub(r"\s*\([^)]*\)\s*$", "", row[0]).strip()
|
base = re.sub(r"\s*\([^)]*\)\s*$", "", row[0]).strip()
|
||||||
@@ -494,7 +517,7 @@ def similar_entries(c, e, pool, cutoff=0.72):
|
|||||||
|
|
||||||
def cmd_pending(a):
|
def cmd_pending(a):
|
||||||
c = Catalog(catalog_path(a.lang))
|
c = Catalog(catalog_path(a.lang))
|
||||||
g = Glossary(a.wiki)
|
g = Glossary(a.wiki, langs=[a.lang])
|
||||||
todo = [e for e in c.active() if needs_translation(e, c.nplurals, a.include_fuzzy)]
|
todo = [e for e in c.active() if needs_translation(e, c.nplurals, a.include_fuzzy)]
|
||||||
batch = todo[a.offset:a.offset + a.limit] if a.limit else todo[a.offset:]
|
batch = todo[a.offset:a.offset + a.limit] if a.limit else todo[a.offset:]
|
||||||
pool = [(x.msgid, x.msgstrs()[0], x.obsolete) for x in c.entries
|
pool = [(x.msgid, x.msgstrs()[0], x.obsolete) for x in c.entries
|
||||||
@@ -533,7 +556,7 @@ def cmd_pending(a):
|
|||||||
|
|
||||||
def cmd_apply(a):
|
def cmd_apply(a):
|
||||||
c = Catalog(catalog_path(a.lang))
|
c = Catalog(catalog_path(a.lang))
|
||||||
g = None if a.no_glossary else Glossary(a.wiki, quiet=True)
|
g = None if a.no_glossary else Glossary(a.wiki, quiet=True, langs=[a.lang])
|
||||||
data = json.loads(Path(a.input).read_text(encoding="utf-8"))
|
data = json.loads(Path(a.input).read_text(encoding="utf-8"))
|
||||||
items = data["entries"] if isinstance(data, dict) else data
|
items = data["entries"] if isinstance(data, dict) else data
|
||||||
idx = c.index()
|
idx = c.index()
|
||||||
@@ -588,7 +611,7 @@ def find_msgfmt():
|
|||||||
|
|
||||||
|
|
||||||
def cmd_check(a):
|
def cmd_check(a):
|
||||||
g = None if a.no_glossary else Glossary(a.wiki, quiet=True)
|
g = None if a.no_glossary else Glossary(a.wiki, quiet=True, langs=a.lang or None)
|
||||||
msgfmt = find_msgfmt()
|
msgfmt = find_msgfmt()
|
||||||
status = 0
|
status = 0
|
||||||
for lang in a.lang or all_langs():
|
for lang in a.lang or all_langs():
|
||||||
@@ -646,7 +669,7 @@ def cmd_lookup(a):
|
|||||||
|
|
||||||
|
|
||||||
def cmd_glossary(a):
|
def cmd_glossary(a):
|
||||||
g = Glossary(a.wiki)
|
g = Glossary(a.wiki, langs=[a.lang])
|
||||||
col = g.column(a.lang)
|
col = g.column(a.lang)
|
||||||
if col is None:
|
if col is None:
|
||||||
print(f"'{a.lang}' has no glossary column yet; add one with glossary-set --set {a.lang}=...")
|
print(f"'{a.lang}' has no glossary column yet; add one with glossary-set --set {a.lang}=...")
|
||||||
@@ -733,6 +756,17 @@ def cmd_candidates(a):
|
|||||||
print(f"{cnt:7} {langs:6} {text}{' [label]' if k in labels else ''} e.g. {ex[:70]}{'…' if len(ex) > 70 else ''}")
|
print(f"{cnt:7} {langs:6} {text}{' [label]' if k in labels else ''} e.g. {ex[:70]}{'…' if len(ex) > 70 else ''}")
|
||||||
|
|
||||||
|
|
||||||
|
def _edit_tsv(path, edit):
|
||||||
|
"""Apply edit(lines) to a glossary TSV, keeping its BOM and line endings."""
|
||||||
|
data = path.read_bytes()
|
||||||
|
bom = data.startswith(b"\xef\xbb\xbf")
|
||||||
|
text = data.decode("utf-8-sig")
|
||||||
|
nl = "\r\n" if "\r\n" in text else "\n"
|
||||||
|
lines = text.splitlines()
|
||||||
|
edit(lines)
|
||||||
|
path.write_bytes((b"\xef\xbb\xbf" if bom else b"") + (nl.join(lines) + nl).encode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def cmd_glossary_set(a):
|
def cmd_glossary_set(a):
|
||||||
wiki = find_wiki(a.wiki)
|
wiki = find_wiki(a.wiki)
|
||||||
if not wiki:
|
if not wiki:
|
||||||
@@ -741,8 +775,21 @@ def cmd_glossary_set(a):
|
|||||||
f" {a.term}: " + ", ".join(a.set) + "\n"
|
f" {a.term}: " + ", ".join(a.set) + "\n"
|
||||||
"Clone https://github.com/OrcaSlicer/OrcaSlicer_WIKI next to this repository, or pass --wiki.", file=sys.stderr)
|
"Clone https://github.com/OrcaSlicer/OrcaSlicer_WIKI next to this repository, or pass --wiki.", file=sys.stderr)
|
||||||
return 2
|
return 2
|
||||||
tsv = wiki / GLOSSARY_TSV
|
gdir = wiki / GLOSSARY_DIR
|
||||||
lock = tsv.with_suffix(".lock")
|
gen = wiki / "generate_glossary.py"
|
||||||
|
if not gen.exists():
|
||||||
|
sys.exit(f"{gen} not found")
|
||||||
|
run_gen = lambda *args: subprocess.run([sys.executable, str(gen), *args], cwd=wiki, capture_output=True, text=True)
|
||||||
|
langs = [l.strip() for l in (gdir / "languages.txt").read_text(encoding="utf-8-sig").splitlines() if l.strip()]
|
||||||
|
values = {}
|
||||||
|
for s in a.set:
|
||||||
|
lang, _, val = s.partition("=")
|
||||||
|
if lang not in langs:
|
||||||
|
sys.exit(f"no glossary language '{lang}' (add it to {GLOSSARY_DIR.as_posix()}/languages.txt)")
|
||||||
|
if "\t" in val or "\n" in val:
|
||||||
|
sys.exit("values cannot contain tabs or line breaks")
|
||||||
|
values[lang] = val.strip()
|
||||||
|
lock = gdir / ".lock"
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
try:
|
try:
|
||||||
fd = os.open(lock, os.O_CREAT | os.O_EXCL)
|
fd = os.open(lock, os.O_CREAT | os.O_EXCL)
|
||||||
@@ -752,50 +799,51 @@ def cmd_glossary_set(a):
|
|||||||
else:
|
else:
|
||||||
sys.exit(f"could not lock {lock}; remove it if no other run is active")
|
sys.exit(f"could not lock {lock}; remove it if no other run is active")
|
||||||
try:
|
try:
|
||||||
data = tsv.read_bytes()
|
terms = (gdir / "terms.tsv").read_text(encoding="utf-8-sig").splitlines()
|
||||||
bom = data.startswith(b"\xef\xbb\xbf")
|
new = not any(l.split("\t")[0] == a.term for l in terms[1:])
|
||||||
text = data.decode("utf-8-sig")
|
if new and not a.description:
|
||||||
nl = "\r\n" if "\r\n" in text else "\n"
|
sys.exit("a new term needs --description (one sentence saying what it is)")
|
||||||
lines = text.splitlines()
|
# an established translation is only replaced on request
|
||||||
header = lines[0].split("\t")
|
conflicts = []
|
||||||
values = {}
|
for lang, v in values.items():
|
||||||
for s in a.set:
|
for line in (gdir / f"{lang}.tsv").read_text(encoding="utf-8-sig").splitlines()[1:]:
|
||||||
lang, _, val = s.partition("=")
|
cells = line.split("\t")
|
||||||
if lang not in header:
|
if cells[0] == a.term and len(cells) > 2 and cells[2].strip() not in MISSING and cells[2] != v:
|
||||||
sys.exit(f"no glossary column '{lang}'")
|
conflicts.append(f"{lang}: '{cells[2]}' -> '{v}'")
|
||||||
if "\t" in val or "\n" in val:
|
|
||||||
sys.exit("values cannot contain tabs or line breaks")
|
|
||||||
values[header.index(lang)] = val.strip()
|
|
||||||
row_i = next((i for i, l in enumerate(lines[1:], 1) if l.split("\t")[0] == a.term), None)
|
|
||||||
new = row_i is None
|
|
||||||
if new:
|
|
||||||
if not a.description:
|
|
||||||
sys.exit("a new term needs --description (one sentence saying what it is)")
|
|
||||||
row = [a.term, a.description] + [""] * (len(header) - 2)
|
|
||||||
lines.append("")
|
|
||||||
row_i = len(lines) - 1
|
|
||||||
else:
|
|
||||||
row = lines[row_i].split("\t")
|
|
||||||
row += [""] * (len(header) - len(row))
|
|
||||||
if a.description:
|
|
||||||
row[1] = a.description
|
|
||||||
conflicts = [f"{header[i]}: '{row[i]}' -> '{v}'" for i, v in values.items() if row[i].strip() not in MISSING and row[i] != v]
|
|
||||||
if conflicts and not a.replace:
|
if conflicts and not a.replace:
|
||||||
sys.exit("established translations differ (pass --replace, and update the catalogs to match):\n " + "\n ".join(conflicts))
|
sys.exit("established translations differ (pass --replace, and update the catalogs to match):\n " + "\n ".join(conflicts))
|
||||||
for i, v in values.items():
|
|
||||||
row[i] = v
|
def edit_terms(lines):
|
||||||
lines[row_i] = "\t".join(row)
|
for i, l in enumerate(lines):
|
||||||
tsv.write_bytes((b"\xef\xbb\xbf" if bom else b"") + (nl.join(lines) + nl).encode("utf-8"))
|
if i and l.split("\t")[0] == a.term:
|
||||||
|
if a.description:
|
||||||
|
lines[i] = f"{a.term}\t{a.description}"
|
||||||
|
return
|
||||||
|
lines.append(f"{a.term}\t{a.description}")
|
||||||
|
if new or a.description:
|
||||||
|
_edit_tsv(gdir / "terms.tsv", edit_terms)
|
||||||
|
r = run_gen("--sync") # copies the term and description into every language file
|
||||||
|
if r.returncode:
|
||||||
|
sys.exit((r.stdout + r.stderr).strip())
|
||||||
|
|
||||||
|
def setter(lang, v):
|
||||||
|
def edit(lines):
|
||||||
|
for i, l in enumerate(lines):
|
||||||
|
cells = l.split("\t")
|
||||||
|
if i and cells[0] == a.term:
|
||||||
|
lines[i] = "\t".join(cells[:2] + [v])
|
||||||
|
return
|
||||||
|
sys.exit(f"{lang}.tsv has no row for '{a.term}'")
|
||||||
|
return edit
|
||||||
|
for lang, v in values.items():
|
||||||
|
_edit_tsv(gdir / f"{lang}.tsv", setter(lang, v))
|
||||||
finally:
|
finally:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
os.unlink(lock)
|
os.unlink(lock)
|
||||||
print(f"glossary: {'added' if new else 'updated'} '{a.term}'")
|
print(f"glossary: {'added' if new else 'updated'} '{a.term}'")
|
||||||
gen = wiki / "generate_glossary.py"
|
r = run_gen("--update")
|
||||||
if gen.exists():
|
print((r.stdout + r.stderr).strip())
|
||||||
r = subprocess.run([sys.executable, str(gen), "--update"], cwd=wiki, capture_output=True, text=True)
|
return r.returncode
|
||||||
print((r.stdout + r.stderr).strip())
|
|
||||||
return r.returncode
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@@ -569,12 +569,19 @@ on the **first** call. So:
|
|||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
**Before GTK starts**, only the environment exists. `CLI::run` (`src/OrcaSlicer.cpp`) branches on
|
**Before GTK starts**, only the environment exists. `CLI::run` (`src/OrcaSlicer.cpp`) sets the NVIDIA
|
||||||
`GDK_BACKEND` (an `x11` prefix means the X11 opt-in). On the default path it forces `GDK_BACKEND=x11`
|
DMABUF workaround and then branches on `GDK_BACKEND` (an `x11` prefix means the X11 opt-in). On both
|
||||||
when wx lacks EGL and `WAYLAND_DISPLAY` is set. It sets `WEBKIT_DISABLE_COMPOSITING_MODE=1`
|
paths, when `/proc/driver/nvidia/version` exists and the linked WebKitGTK honours the switch (>= 2.44,
|
||||||
(non-replacing) only when both `DISPLAY` and `WAYLAND_DISPLAY` are set, and calls `XInitThreads()`
|
`WebView::SupportsForceSharedMemory()`), it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and
|
||||||
|
`WEBKIT_FORCE_DMABUF_RENDERER=1` (non-replacing): the proprietary driver cannot back WebKit's hardware
|
||||||
|
DMABUF renderer. On a hypervisor guest (`/proc/cpuinfo` `hypervisor` flag) and WebKitGTK >= 2.44 it sets
|
||||||
|
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` alone, since virtual GPUs cannot back the hardware path either. On the default path it forces `GDK_BACKEND=x11` when wx lacks EGL and `WAYLAND_DISPLAY`
|
||||||
|
is set, and sets `WEBKIT_DISABLE_COMPOSITING_MODE=1` (non-replacing) inside that branch when the linked
|
||||||
|
WebKitGTK is older than 2.42: a forced X11 backend in a Wayland session is the only default-path case
|
||||||
|
that runs through XWayland, which `DISPLAY` and `WAYLAND_DISPLAY` alone do not tell you (a native
|
||||||
|
Wayland app inherits both). It calls `XInitThreads()`
|
||||||
only when `DISPLAY` is set. With neither variable set, the GUI refuses to start ("Neither DISPLAY nor
|
only when `DISPLAY` is set. With neither variable set, the GUI refuses to start ("Neither DISPLAY nor
|
||||||
WAYLAND_DISPLAY set"). The details and the WebKit rule (c12912e0df) are in
|
WAYLAND_DISPLAY set"). The details and the WebKit rules (c12912e0df) are in
|
||||||
`references/webview-gl-aui-media.md` §WebKitGTK on Linux sessions.
|
`references/webview-gl-aui-media.md` §WebKitGTK on Linux sessions.
|
||||||
|
|
||||||
**wx's own detectors**, for reference:
|
**wx's own detectors**, for reference:
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ available; GTK2/WebKit1 is an opt-out configuration the GUI does not support.
|
|||||||
11. A web host that re-themes in place handles `EVT_WEBVIEW_RECREATED` without `Skip()`; one that
|
11. A web host that re-themes in place handles `EVT_WEBVIEW_RECREATED` without `Skip()`; one that
|
||||||
needs a reload lets it through. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
needs a reload lets it through. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
||||||
12. Keep `WebViewWebKit`'s destructor removing the `"wx"` handler. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
12. Keep `WebViewWebKit`'s destructor removing the `"wx"` handler. §[Orca wrapper](#orca-webview-wrapper-widgetswebview)
|
||||||
13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond Orca's default-path XWayland case, and never
|
13. Do not widen `WEBKIT_DISABLE_COMPOSITING_MODE` beyond the no-EGL default path where Orca forces
|
||||||
|
`GDK_BACKEND=x11`, for WebKitGTK older than 2.42, and never
|
||||||
make a page's progress depend only on a C++→JS callback. §[WebKitGTK on Linux](#webkitgtk-on-linux-sessions)
|
make a page's progress depend only on a C++→JS callback. §[WebKitGTK on Linux](#webkitgtk-on-linux-sessions)
|
||||||
14. GL attribute lists: legacy `int[]` lists end with `0` and spell out `WX_GL_RGBA` and
|
14. GL attribute lists: legacy `int[]` lists end with `0` and spell out `WX_GL_RGBA` and
|
||||||
`WX_GL_DOUBLEBUFFER`; `wxGLAttributes`/`wxGLContextAttrs` end with `EndList()`; MSAA is requested
|
`WX_GL_DOUBLEBUFFER`; `wxGLAttributes`/`wxGLContextAttrs` end with `EndList()`; MSAA is requested
|
||||||
@@ -567,33 +568,74 @@ vue-resize workaround script and sets a persistent SQLite cookie store on the vi
|
|||||||
## WebKitGTK on Linux sessions
|
## WebKitGTK on Linux sessions
|
||||||
|
|
||||||
**Mechanism.** `CLI::run` (`src/OrcaSlicer.cpp`, under `#ifdef __WXGTK__`, before GTK initialises)
|
**Mechanism.** `CLI::run` (`src/OrcaSlicer.cpp`, under `#ifdef __WXGTK__`, before GTK initialises)
|
||||||
branches on `GDK_BACKEND`:
|
sets the DMABUF workarounds and then branches on `GDK_BACKEND`:
|
||||||
|
- **Both paths**, before the split: when `/proc/driver/nvidia/version` exists and the linked WebKitGTK
|
||||||
|
honours the switch (>= 2.44, `WebView::SupportsForceSharedMemory()`), it sets
|
||||||
|
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` and `WEBKIT_FORCE_DMABUF_RENDERER=1` non-replacing. The
|
||||||
|
proprietary driver cannot back WebKit's hardware DMABUF renderer, so the shared-memory transport keeps
|
||||||
|
accelerated compositing instead of dropping it; `WEBKIT_FORCE_DMABUF_RENDERER` clears the
|
||||||
|
Debian/Ubuntu/openSUSE `isNVIDIA()` early return, which otherwise returns before the FORCE_SHM check.
|
||||||
|
- **Hypervisor guests**, same position: when `is_hypervisor_guest()` (the `hypervisor` flag in
|
||||||
|
`/proc/cpuinfo`) and WebKitGTK >= 2.44, it sets `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` non-replacing.
|
||||||
|
Virtual GPUs (VirtualBox VMSVGA, VMware, QEMU) cannot back the hardware DMABUF path either, and
|
||||||
|
FORCE_SHM alone was confirmed to fix web views in VirtualBox; the `WEBKIT_FORCE_DMABUF_RENDERER` pair
|
||||||
|
is not needed without the Debian `isNVIDIA()` patch. The flag is x86-only, so ARM guests are not covered.
|
||||||
- **Default path** (`GDK_BACKEND` unset or not starting with `x11`): if wx lacks EGL (`!wxHAS_EGL`) and
|
- **Default path** (`GDK_BACKEND` unset or not starting with `x11`): if wx lacks EGL (`!wxHAS_EGL`) and
|
||||||
`WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`; it sets `WEBKIT_DISABLE_COMPOSITING_MODE=1`
|
`WAYLAND_DISPLAY` is set, it forces `GDK_BACKEND=x11`, and in that same branch it sets
|
||||||
non-replacing **only** when both `DISPLAY` and `WAYLAND_DISPLAY` are non-empty (a Wayland session with
|
`WEBKIT_DISABLE_COMPOSITING_MODE=1` non-replacing when the linked WebKitGTK predates 2.42
|
||||||
XWayland available — the session, not the backend GTK will pick); `XInitThreads()` runs only when
|
(`WebView::NeedsCompositingWorkaround()`). That forced X11 backend in a Wayland session is the only
|
||||||
`DISPLAY` is set.
|
default-path case that really runs through XWayland; `DISPLAY` and `WAYLAND_DISPLAY` alone do not
|
||||||
|
identify it, because a native Wayland app inherits both. `XInitThreads()` runs only when `DISPLAY` is
|
||||||
|
set.
|
||||||
- **`GDK_BACKEND=x11…` opt-in path**: sets `DRI_PRIME=1` (and the NVIDIA PRIME variables when
|
- **`GDK_BACKEND=x11…` opt-in path**: sets `DRI_PRIME=1` (and the NVIDIA PRIME variables when
|
||||||
`/proc/driver/nvidia/version` exists), calls `XInitThreads()`, and deliberately does **not** disable
|
`/proc/driver/nvidia/version` exists), calls `XInitThreads()`, and deliberately does **not** disable
|
||||||
compositing (the comment: the WebKit2GTK XWayland bug appears fixed in WebKit2GTK ≥ 2.42, and leaving
|
compositing, which keeps hardware acceleration for Device / Setup Wizard / login pages.
|
||||||
compositing on keeps hardware acceleration for Device / Setup Wizard / login pages).
|
|
||||||
|
|
||||||
Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_running_on_x11()`
|
Runtime backend detection elsewhere uses Orca's `is_running_on_wayland()` / `is_running_on_x11()`
|
||||||
(see `references/platforms.md`), not these environment variables.
|
(see `references/platforms.md`), not these environment variables.
|
||||||
|
|
||||||
**Pitfall.**
|
**Pitfall.**
|
||||||
- **Rule:** Set `WEBKIT_DISABLE_COMPOSITING_MODE` only on the default path in Wayland sessions,
|
- **Rule:** On NVIDIA and hypervisor guests reach for `WEBKIT_DMABUF_RENDERER_FORCE_SHM` before
|
||||||
non-replacing (`setenv(..., false)`, so a value the user already exported wins), before GTK
|
`WEBKIT_DISABLE_COMPOSITING_MODE`. **Why:** the proprietary driver and virtual GPUs cannot back WebKit's
|
||||||
initialises; never unconditionally. Keep JS-side fallbacks so a page never
|
hardware DMABUF renderer, leaving web views blank or slow; FORCE_SHM keeps accelerated compositing and only
|
||||||
|
skips the hardware path, while disabling compositing drops it. Threaded scrolling is a separate,
|
||||||
|
release-dependent default (off in 2.44/2.45, on from 2.46). `WEBKIT_DISABLE_DMABUF_RENDERER` is not a
|
||||||
|
substitute — it is read first, leaves the transport set empty (no compositing from 2.44 on, where the
|
||||||
|
X11/Wayland fallback renderers were removed) and has a reported crash path. On Debian/Ubuntu and
|
||||||
|
openSUSE the `isNVIDIA()` patch returns before the FORCE_SHM check, so `WEBKIT_FORCE_DMABUF_RENDERER=1`
|
||||||
|
must clear it first; that variable exists only in those patches. WebKit reads all of these once per
|
||||||
|
process, before the first WebView.
|
||||||
|
The test is `/proc/driver/nvidia/version`, so a hybrid laptop that renders on its iGPU also takes the
|
||||||
|
shared-memory path, which is a per-frame GPU readback rather than zero-copy; exporting
|
||||||
|
`WEBKIT_DMABUF_RENDERER_FORCE_SHM=0` in the environment restores the hardware path.
|
||||||
|
```cpp
|
||||||
|
// Wrong: kills compositing and threaded scrolling (and can crash on modern WebKit)
|
||||||
|
::setenv("WEBKIT_DISABLE_DMABUF_RENDERER", "1", false);
|
||||||
|
// Right: keep compositing, skip only the hardware DMABUF path
|
||||||
|
if (::access("/proc/driver/nvidia/version", F_OK) == 0 && WebView::SupportsForceSharedMemory()) {
|
||||||
|
::setenv("WEBKIT_DMABUF_RENDERER_FORCE_SHM", "1", /*replace*/ false);
|
||||||
|
::setenv("WEBKIT_FORCE_DMABUF_RENDERER", "1", /*replace*/ false);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Cite: WebKit 2.52.6 `Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.cpp`
|
||||||
|
(`rendererBufferTransportMode()`), Debian `disable-nvidia-dmabuf.patch`, WebKit bug 262607.
|
||||||
|
- **Rule:** Set `WEBKIT_DISABLE_COMPOSITING_MODE` only on the default path, in the branch where wx
|
||||||
|
lacks EGL and Orca forces `GDK_BACKEND=x11`, non-replacing (`setenv(..., false)`, so a value the user
|
||||||
|
already exported wins), before GTK
|
||||||
|
initialises; never unconditionally, and only for the WebKitGTK releases that need it (older than
|
||||||
|
2.42, `WebView::NeedsCompositingWorkaround()`). Keep JS-side fallbacks so a page never
|
||||||
waits forever for a C++→JS call.
|
waits forever for a C++→JS call.
|
||||||
**Why:** WebKit2GTK accelerated compositing could fail silently under XWayland, leaving web views
|
**Why:** WebKit2GTK accelerated compositing could fail silently under XWayland before 2.42, leaving
|
||||||
blank (Setup Wizard stuck on "Loading..."); disabling it everywhere needlessly drops hardware
|
web views blank (Setup Wizard stuck on "Loading..."); the variable also turns off threaded scrolling,
|
||||||
acceleration; without the JS timeout the user is stuck when the signal is lost.
|
so applying it on a newer WebKit needlessly drops both GPU compositing and async scrolling (the
|
||||||
|
Device tab loses its smoothness); without the JS timeout the user is stuck when the signal is lost.
|
||||||
```cpp
|
```cpp
|
||||||
// Wrong: unconditional, kills HW acceleration everywhere
|
// Wrong: unconditional, kills HW acceleration everywhere
|
||||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", false);
|
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", false);
|
||||||
// Right (default path only): non-replacing, before GTK init, Wayland session with XWayland
|
// Right (default path only): non-replacing, before GTK init, WebKitGTK < 2.42,
|
||||||
if (display && *display && wayland && *wayland)
|
// and only in the branch that forces GDK_BACKEND=x11 (wx without EGL), the
|
||||||
|
// case that runs through XWayland
|
||||||
|
if (WebView::NeedsCompositingWorkaround() && wayland && *wayland)
|
||||||
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /*replace*/ false);
|
::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /*replace*/ false);
|
||||||
```
|
```
|
||||||
Cite: c12912e0df (`src/OrcaSlicer.cpp`; `resources/web/guide/0/load.js` `OnInit`
|
Cite: c12912e0df (`src/OrcaSlicer.cpp`; `resources/web/guide/0/load.js` `OnInit`
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ on:
|
|||||||
- 'build_linux.sh'
|
- 'build_linux.sh'
|
||||||
- 'build_win.bat'
|
- 'build_win.bat'
|
||||||
- 'scripts/test_build_win.ps1'
|
- 'scripts/test_build_win.ps1'
|
||||||
|
- 'scripts/check_exception_throw_info.ps1'
|
||||||
|
- 'scripts/test_check_exception_throw_info.ps1'
|
||||||
- 'build_release_macos.sh'
|
- 'build_release_macos.sh'
|
||||||
- 'scripts/build_preset_cache.*'
|
- 'scripts/build_preset_cache.*'
|
||||||
- 'scripts/flatpak/**'
|
- 'scripts/flatpak/**'
|
||||||
@@ -41,6 +43,8 @@ on:
|
|||||||
- 'build_linux.sh'
|
- 'build_linux.sh'
|
||||||
- 'build_win.bat'
|
- 'build_win.bat'
|
||||||
- 'scripts/test_build_win.ps1'
|
- 'scripts/test_build_win.ps1'
|
||||||
|
- 'scripts/check_exception_throw_info.ps1'
|
||||||
|
- 'scripts/test_check_exception_throw_info.ps1'
|
||||||
- 'build_release_macos.sh'
|
- 'build_release_macos.sh'
|
||||||
- 'scripts/build_preset_cache.*'
|
- 'scripts/build_preset_cache.*'
|
||||||
- 'scripts/flatpak/**'
|
- 'scripts/flatpak/**'
|
||||||
@@ -84,6 +88,10 @@ jobs:
|
|||||||
shell: powershell
|
shell: powershell
|
||||||
run: .\scripts\test_build_win.ps1
|
run: .\scripts\test_build_win.ps1
|
||||||
|
|
||||||
|
- name: Run the exception throw info check tests
|
||||||
|
shell: powershell
|
||||||
|
run: .\scripts\test_check_exception_throw_info.ps1
|
||||||
|
|
||||||
build_linux:
|
build_linux:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
@@ -65,15 +65,6 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
leg="${{ runner.os }}-${{ inputs.arch || 'amd64' }}${{ runner.os == 'Windows' && format('-{0}', inputs.compiler) || '' }}"
|
leg="${{ runner.os }}-${{ inputs.arch || 'amd64' }}${{ runner.os == 'Windows' && format('-{0}', inputs.compiler) || '' }}"
|
||||||
# clang-cl refuses a precompiled header from another cl.exe build and ccache
|
|
||||||
# does not hash that build, so each one gets its own cache. The build number
|
|
||||||
# is read from cl.exe itself; the toolset directory keeps its name across patches.
|
|
||||||
if [ "${{ runner.os }}" = Windows ]; then
|
|
||||||
vswhere='/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe'
|
|
||||||
toolset=$(tr -d '\r\n' < "$("$vswhere" -latest -products '*' -find 'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt' | tr -d '\r')")
|
|
||||||
cl=$("$vswhere" -latest -products '*' -find 'VC\Tools\MSVC\'"$toolset"'\**\cl.exe' | tr -d '\r' | head -1)
|
|
||||||
leg="$leg-vc$("$cl" 2>&1 | grep -o -E 'Version [0-9.]+' | cut -d' ' -f2)"
|
|
||||||
fi
|
|
||||||
echo "CCACHE_LEG=$leg" >> "$GITHUB_ENV"
|
echo "CCACHE_LEG=$leg" >> "$GITHUB_ENV"
|
||||||
echo "CCACHE_ENTRY=ccache-$leg-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
|
echo "CCACHE_ENTRY=ccache-$leg-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
@@ -552,6 +543,13 @@ jobs:
|
|||||||
name: OrcaSlicer_profile_validator_Windows_${{ env.ver }}
|
name: OrcaSlicer_profile_validator_Windows_${{ env.ver }}
|
||||||
path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe
|
path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe
|
||||||
|
|
||||||
|
- name: Check exception throw info Win
|
||||||
|
if: runner.os == 'Windows' && inputs.compiler == 'clang'
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
|
# After the uploads, so a failure still leaves the build and its PDB to inspect, and before any deploy.
|
||||||
|
shell: pwsh
|
||||||
|
run: scripts\check_exception_throw_info.ps1 -BuildDir $env:BUILD_DIR
|
||||||
|
|
||||||
- name: Deploy Windows release portable
|
- name: Deploy Windows release portable
|
||||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||||
uses: ./.github/actions/deploy-nightly
|
uses: ./.github/actions/deploy-nightly
|
||||||
|
|||||||
@@ -232,6 +232,31 @@ jobs:
|
|||||||
mkdir -p ${{ runner.temp }}/profile-check-results
|
mkdir -p ${{ runner.temp }}/profile-check-results
|
||||||
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
||||||
|
|
||||||
|
# Builds a readable diff of the custom G-code the PR changes, which GitHub shows as
|
||||||
|
# one long line per setting, for check_profiles_comment.yml to post.
|
||||||
|
- name: Diff custom G-code
|
||||||
|
if: ${{ always() && github.event_name == 'pull_request' }}
|
||||||
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||||
|
run: |
|
||||||
|
git fetch --no-tags --depth=2 origin "$(git rev-parse HEAD)"
|
||||||
|
results=${{ runner.temp }}/profile-check-results
|
||||||
|
diff=${{ runner.temp }}/gcode_diff.md
|
||||||
|
# HEAD is the PR's merge commit, so HEAD^1 is the base it merges onto.
|
||||||
|
python3 ./scripts/orca_profile_tool.py gcode-diff --base HEAD^1 --head HEAD > "$diff"
|
||||||
|
if [ -s "$diff" ]; then
|
||||||
|
{
|
||||||
|
echo "<!-- profile-gcode-diff-comment -->"
|
||||||
|
cat "$diff"
|
||||||
|
echo ""
|
||||||
|
# The comment workflow finds this line as the only one starting with <sub>.
|
||||||
|
echo "<sub>For commit ${PR_HEAD_SHA} of this PR.</sub>"
|
||||||
|
} > "$results/gcode_diff.md"
|
||||||
|
fi
|
||||||
|
# Tells the comment workflow that a missing gcode_diff.md means no G-code changed.
|
||||||
|
touch "$results/gcode_diff_done.txt"
|
||||||
|
|
||||||
- name: Prepare comment artifact
|
- name: Prepare comment artifact
|
||||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.profile_tool.outcome == 'failure' || steps.legacy_compat.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
if: ${{ always() && github.event_name == 'pull_request' && (steps.profile_tool.outcome == 'failure' || steps.legacy_compat.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
GH_REPO: ${{ github.repository }}
|
GH_REPO: ${{ github.repository }}
|
||||||
|
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||||
run: |
|
run: |
|
||||||
if [ ! -f pr_number.txt ]; then
|
if [ ! -f pr_number.txt ]; then
|
||||||
echo "No pr_number.txt in artifact, skipping."
|
echo "No pr_number.txt in artifact, skipping."
|
||||||
@@ -49,18 +50,72 @@ jobs:
|
|||||||
echo "Invalid PR number: $PR_NUMBER"
|
echo "Invalid PR number: $PR_NUMBER"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# PR code wrote the artifact, so only a run for the named PR's current head may post.
|
||||||
|
if [ -z "$HEAD_SHA" ]; then
|
||||||
|
echo "The triggering run names no head commit."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! PR_HEAD=$(gh api "repos/${GH_REPO}/pulls/${PR_NUMBER}" --jq .head.sha); then
|
||||||
|
echo "Cannot look up PR #${PR_NUMBER}."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$HEAD_SHA" != "$PR_HEAD" ]; then
|
||||||
|
echo "${HEAD_SHA} is not the head of PR #${PR_NUMBER}; skipping."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Lists every bot comment on the PR, one JSON object per line.
|
||||||
|
COMMENTS=$(gh api --paginate "repos/${GH_REPO}/issues/${PR_NUMBER}/comments" \
|
||||||
|
--jq '.[] | select(.user.login == "github-actions[bot]") | {id, body} | @json')
|
||||||
|
|
||||||
# Delete prior comments matching the marker (from check_profiles.yml) or the legacy heading.
|
# Delete prior comments matching the marker (from check_profiles.yml) or the legacy heading.
|
||||||
OLD_IDS=$(gh api --paginate "repos/${GH_REPO}/issues/${PR_NUMBER}/comments" \
|
OLD_IDS=$(printf '%s\n' "$COMMENTS" | jq -r 'select((.body | startswith("<!-- profile-validation-comment -->")) or (.body | startswith("## :x: Profile Validation Errors"))) | .id')
|
||||||
--jq '.[] | select(.user.login == "github-actions[bot]") | select((.body | startswith("<!-- profile-validation-comment -->")) or (.body | startswith("## :x: Profile Validation Errors"))) | .id')
|
|
||||||
for comment_id in $OLD_IDS; do
|
for comment_id in $OLD_IDS; do
|
||||||
echo "Deleting outdated profile-validation comment ${comment_id}"
|
echo "Deleting outdated profile-validation comment ${comment_id}"
|
||||||
gh api -X DELETE "repos/${GH_REPO}/issues/comments/${comment_id}" || true
|
gh api -X DELETE "repos/${GH_REPO}/issues/comments/${comment_id}" || true
|
||||||
done
|
done
|
||||||
|
|
||||||
# Post a new comment only when validation failed (pr_comment.md present).
|
# Post a new comment only when validation failed (pr_comment.md present).
|
||||||
|
# A failed post fails the job only after the G-code diff is handled.
|
||||||
|
failed=0
|
||||||
if [ -f pr_comment.md ]; then
|
if [ -f pr_comment.md ]; then
|
||||||
gh pr comment "$PR_NUMBER" --body-file pr_comment.md
|
gh pr comment "$PR_NUMBER" --body-file pr_comment.md || failed=1
|
||||||
else
|
else
|
||||||
echo "Validation succeeded; cleaned up prior comments without posting."
|
echo "Validation succeeded; cleaned up prior comments without posting."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Makes the G-code diff comment match gcode_diff.md, or deletes it if there is none.
|
||||||
|
update_gcode_diff_comment() {
|
||||||
|
if [ ! -f gcode_diff_done.txt ]; then
|
||||||
|
echo "The G-code diff step did not finish; leaving any G-code diff comment as it is."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
GCODE_IDS=$(printf '%s\n' "$COMMENTS" | jq -r 'select(.body | startswith("<!-- profile-gcode-diff-comment -->")) | .id')
|
||||||
|
if [ -f gcode_diff.md ] && [ "$(wc -c < gcode_diff.md)" -gt 65536 ]; then
|
||||||
|
echo "gcode_diff.md is over GitHub's comment limit; not posting it."
|
||||||
|
rm gcode_diff.md
|
||||||
|
fi
|
||||||
|
if [ -f gcode_diff.md ] && [ "$(echo "$GCODE_IDS" | wc -w)" -eq 1 ]; then
|
||||||
|
OLD_BODY=$(printf '%s\n' "$COMMENTS" | jq -r --argjson id "$GCODE_IDS" 'select(.id == $id) | .body' | tr -d '\r')
|
||||||
|
NEW_BODY=$(tr -d '\r' < gcode_diff.md)
|
||||||
|
if [ "$OLD_BODY" = "$NEW_BODY" ]; then
|
||||||
|
echo "G-code diff unchanged; keeping comment ${GCODE_IDS}."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# Edits in place when only the <sub> line differs, since edits notify nobody.
|
||||||
|
if [ "$(grep -v '^<sub>' <<< "$OLD_BODY")" = "$(grep -v '^<sub>' <<< "$NEW_BODY")" ]; then
|
||||||
|
echo "G-code diff unchanged at a new commit; updating comment ${GCODE_IDS}."
|
||||||
|
gh api -X PATCH "repos/${GH_REPO}/issues/comments/${GCODE_IDS}" -F body=@gcode_diff.md > /dev/null
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
for comment_id in $GCODE_IDS; do
|
||||||
|
echo "Deleting outdated G-code diff comment ${comment_id}"
|
||||||
|
gh api -X DELETE "repos/${GH_REPO}/issues/comments/${comment_id}" || true
|
||||||
|
done
|
||||||
|
if [ -f gcode_diff.md ]; then
|
||||||
|
gh pr comment "$PR_NUMBER" --body-file gcode_diff.md
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
update_gcode_diff_comment
|
||||||
|
exit "$failed"
|
||||||
@@ -91,7 +91,7 @@ See `.claude/skills/orca-translations/references/source-audit.md` for the full c
|
|||||||
### Terminology
|
### Terminology
|
||||||
|
|
||||||
- Use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language, and terms that must stay in English (brand/product names, acronyms, materials, file formats, G-code tokens, macros/variables/identifiers) are not translated.
|
- Use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language, and terms that must stay in English (brand/product names, acronyms, materials, file formats, G-code tokens, macros/variables/identifiers) are not translated.
|
||||||
- If a term's established translation changes, update both the affected `.po` files and the glossary (`localization_glossary.tsv`, then regenerate) so they stay in sync.
|
- If a term's established translation changes, update both the affected `.po` files and the glossary (`developer_reference/glossary/<lang>.tsv` in the wiki, then regenerate) so they stay in sync.
|
||||||
- Translate the *meaning*, not the words. Check what the string actually controls before translating it — English reuses one word for different things. `Flow ratio` (multiplier), `Flow Rate` (throughput) and `Flow Dynamics` (pressure compensation) are three different terms; `extruder` may mean the toolhead, the feeder motor, or the nozzle depending on the string.
|
- Translate the *meaning*, not the words. Check what the string actually controls before translating it — English reuses one word for different things. `Flow ratio` (multiplier), `Flow Rate` (throughput) and `Flow Dynamics` (pressure compensation) are three different terms; `extruder` may mean the toolhead, the feeder motor, or the nozzle depending on the string.
|
||||||
- Reuse one template per recurring message shape (`Failed to connect to …`, `Are you sure you want to …?`), even where the English wording varies.
|
- Reuse one template per recurring message shape (`Failed to connect to …`, `Are you sure you want to …?`), even where the English wording varies.
|
||||||
|
|
||||||
|
|||||||
@@ -288,6 +288,19 @@ if (APPLE)
|
|||||||
# Type"); Ninja/-Wall does not, and under -Werror it fails Xcode builds on code CI accepts.
|
# Type"); Ninja/-Wall does not, and under -Werror it fails Xcode builds on code CI accepts.
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION "NO")
|
set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION "NO")
|
||||||
|
|
||||||
|
# The Xcode generator ignores CMAKE_<LANG>_COMPILER_LAUNCHER, so hand the launcher to
|
||||||
|
# Xcode's own Compiler Launcher setting, which wraps every clang compile (C, C++,
|
||||||
|
# Objective-C++ and the precompiled header) with one program: the C++ launcher wins when
|
||||||
|
# both are set. The setting takes a single program path, not a CMake launcher list.
|
||||||
|
# Xcode versions without it ignore it and build uncached.
|
||||||
|
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||||
|
if (CMAKE_CXX_COMPILER_LAUNCHER)
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_C_COMPILER_LAUNCHER "${CMAKE_CXX_COMPILER_LAUNCHER}")
|
||||||
|
elseif (CMAKE_C_COMPILER_LAUNCHER)
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_C_COMPILER_LAUNCHER "${CMAKE_C_COMPILER_LAUNCHER}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Orca: IS_CROSS_COMPILE: ${IS_CROSS_COMPILE}")
|
message(STATUS "Orca: IS_CROSS_COMPILE: ${IS_CROSS_COMPILE}")
|
||||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
set(CMAKE_INSTALL_RPATH "$ORIGIN")
|
set(CMAKE_INSTALL_RPATH "$ORIGIN")
|
||||||
@@ -308,6 +321,14 @@ if (IS_CROSS_COMPILE)
|
|||||||
set(BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
set(BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# With a precompiled header, clang-cl can omit an exception type's copy constructor from its throw info,
|
||||||
|
# so copies of the exception share and double-free their data: https://github.com/llvm/llvm-project/issues/53486
|
||||||
|
if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
message(STATUS "clang-cl: building without the precompiled header (llvm/llvm-project#53486)")
|
||||||
|
set_property(CACHE SLIC3R_PCH PROPERTY HELPSTRING "Use precompiled headers (ignored with clang-cl, llvm/llvm-project#53486)")
|
||||||
|
set(SLIC3R_PCH OFF)
|
||||||
|
endif ()
|
||||||
|
|
||||||
# Print out the SLIC3R_* cache options
|
# Print out the SLIC3R_* cache options
|
||||||
get_cmake_property(_cache_vars CACHE_VARIABLES)
|
get_cmake_property(_cache_vars CACHE_VARIABLES)
|
||||||
list (SORT _cache_vars)
|
list (SORT _cache_vars)
|
||||||
|
|||||||
+17
-3
@@ -22,7 +22,7 @@ function usage() {
|
|||||||
echo " -g: run the requested build steps inside a Docker/Podman Ubuntu 24.04 container similar to the GitHub Actions Linux runner"
|
echo " -g: run the requested build steps inside a Docker/Podman Ubuntu 24.04 container similar to the GitHub Actions Linux runner"
|
||||||
echo " -h: prints this help text"
|
echo " -h: prints this help text"
|
||||||
echo " -i: build the Orca Slicer AppImage (optional)"
|
echo " -i: build the Orca Slicer AppImage (optional)"
|
||||||
echo " -p: boost ccache hit rate by disabling precompiled headers (default: ON)"
|
echo " -p: disable precompiled headers (on by default): more ccache hits after header changes, slower misses"
|
||||||
echo " -r: skip RAM and disk checks (low RAM compiling)"
|
echo " -r: skip RAM and disk checks (low RAM compiling)"
|
||||||
echo " -s: build the Orca Slicer (optional)"
|
echo " -s: build the Orca Slicer (optional)"
|
||||||
echo " -t: build tests (optional), requires -s flag"
|
echo " -t: build tests (optional), requires -s flag"
|
||||||
@@ -473,8 +473,8 @@ fi
|
|||||||
# cmake 4.x compatibility workaround
|
# cmake 4.x compatibility workaround
|
||||||
export CMAKE_POLICY_VERSION_MINIMUM=3.5
|
export CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||||
|
|
||||||
DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release | tr -d '"')
|
DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release | tr -d "'\"")
|
||||||
DISTRIBUTION_LIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d '"')
|
DISTRIBUTION_LIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d "'\"")
|
||||||
# Check for direct distribution match to Ubuntu/Debian
|
# Check for direct distribution match to Ubuntu/Debian
|
||||||
if [ "${DISTRIBUTION}" == "ubuntu" ] || [ "${DISTRIBUTION}" == "linuxmint" ] ; then
|
if [ "${DISTRIBUTION}" == "ubuntu" ] || [ "${DISTRIBUTION}" == "linuxmint" ] ; then
|
||||||
DISTRIBUTION="debian"
|
DISTRIBUTION="debian"
|
||||||
@@ -549,6 +549,20 @@ fi
|
|||||||
if [ -n "${CMAKE_CCACHE}" ] ; then
|
if [ -n "${CMAKE_CCACHE}" ] ; then
|
||||||
echo "${CMAKE_CCACHE} found, enabling compiler caching..."
|
echo "${CMAKE_CCACHE} found, enabling compiler caching..."
|
||||||
export CMAKE_CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_CCACHE}" -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CCACHE}")
|
export CMAKE_CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_CCACHE}" -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CCACHE}")
|
||||||
|
# The same ccache settings as the CI build. Without this sloppiness ccache refuses every
|
||||||
|
# compile that uses the precompiled header, which is most of OrcaSlicer, and skips headers
|
||||||
|
# a checkout has just written. It is added to the sloppiness already configured, and
|
||||||
|
# CCACHE_SLOPPINESS or CCACHE_(NO)DEPEND set in the environment win.
|
||||||
|
if [[ "$(basename "${CMAKE_CCACHE}")" == ccache ]] ; then
|
||||||
|
if [[ -z "${CCACHE_SLOPPINESS+x}" ]] ; then
|
||||||
|
CCACHE_SLOPPINESS=$("${CMAKE_CCACHE}" --get-config sloppiness 2>/dev/null || true)
|
||||||
|
export CCACHE_SLOPPINESS="${CCACHE_SLOPPINESS:+${CCACHE_SLOPPINESS},}pch_defines,time_macros,include_file_mtime,include_file_ctime"
|
||||||
|
fi
|
||||||
|
# Hash the includes the compiler reports instead of preprocessing every miss.
|
||||||
|
if [[ -z "${CCACHE_DEPEND+x}${CCACHE_NODEPEND+x}" ]] ; then
|
||||||
|
export CCACHE_DEPEND=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "Note: ccache or sccache are not found. Install either of them for faster rebuilds."
|
echo "Note: ccache or sccache are not found. Install either of them for faster rebuilds."
|
||||||
fi
|
fi
|
||||||
|
|||||||
+75
-3
@@ -47,7 +47,7 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do
|
|||||||
u )
|
u )
|
||||||
export BUILD_TARGET="universal"
|
export BUILD_TARGET="universal"
|
||||||
;;
|
;;
|
||||||
h ) echo "Usage: ./build_release_macos.sh [-d]"
|
h ) echo "Usage: ./build_release_macos.sh [-d] [-- CMAKE_ARGS...]"
|
||||||
echo " -d: Build deps only"
|
echo " -d: Build deps only"
|
||||||
echo " -a: Set ARCHITECTURE (arm64 or x86_64 or universal)"
|
echo " -a: Set ARCHITECTURE (arm64 or x86_64 or universal)"
|
||||||
echo " -s: Build slicer only"
|
echo " -s: Build slicer only"
|
||||||
@@ -60,13 +60,33 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do
|
|||||||
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
|
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
|
||||||
echo " -j: Set the number of parallel build jobs (CMAKE_BUILD_PARALLEL_LEVEL)"
|
echo " -j: Set the number of parallel build jobs (CMAKE_BUILD_PARALLEL_LEVEL)"
|
||||||
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
|
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
|
||||||
|
echo " -- CMAKE_ARGS...: pass everything after '--' to the cmake configure step of the deps (-d) and slicer (-s) builds,"
|
||||||
|
echo " e.g. -DDESTDIR=<dir> for the deps, -DCMAKE_PREFIX_PATH=<dir>/usr/local -DSLIC3R_PCH=OFF for the slicer, --fresh."
|
||||||
|
echo " They come last on the cmake command line. Use absolute paths: cmake runs in the build directory."
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
: )
|
||||||
|
echo "Option -${OPTARG} requires an argument, aborting."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
* )
|
* )
|
||||||
|
echo "Unknown option -${OPTARG}, aborting. CMake arguments must follow '--'."
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# getopts stops at '--'; whatever follows is handed to cmake unchanged.
|
||||||
|
if [[ ${OPTIND} -le $# ]] ; then
|
||||||
|
separator_index=$((OPTIND-1))
|
||||||
|
if [[ "${!separator_index}" != "--" ]] ; then
|
||||||
|
echo "Unexpected argument '${!OPTIND}': cmake arguments must follow '--', aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
EXTRA_CMAKE_ARGS=("$@")
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
|
|
||||||
if [ -z "$ARCH" ]; then
|
if [ -z "$ARCH" ]; then
|
||||||
@@ -111,6 +131,54 @@ else
|
|||||||
export CMAKE_POLICY_COMPAT=""
|
export CMAKE_POLICY_COMPAT=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Compiler cache, as in build_linux.sh. The program comes from CMAKE_CCACHE, else from a
|
||||||
|
# launcher already set in the environment (the CI build sets ccache there), else sccache or
|
||||||
|
# ccache from PATH; one program serves both languages. Each run applies its own choice to the
|
||||||
|
# build directories, replacing a launcher an earlier run or a hand-run configure recorded.
|
||||||
|
CMAKE_CCACHE_ARGS=()
|
||||||
|
CCACHE_VAR=""
|
||||||
|
for var in CMAKE_CCACHE CMAKE_CXX_COMPILER_LAUNCHER CMAKE_C_COMPILER_LAUNCHER; do
|
||||||
|
if [ -n "${!var:-}" ]; then
|
||||||
|
CCACHE_VAR=$var
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ -n "$CCACHE_VAR" ]; then
|
||||||
|
CCACHE_PROGRAM=${!CCACHE_VAR}
|
||||||
|
echo "Checking ${CCACHE_VAR} environment variable for compiler cache program..."
|
||||||
|
CMAKE_CCACHE=$(command -v "${CCACHE_PROGRAM}") || {
|
||||||
|
echo "${CCACHE_VAR} environment variable is set to '${CCACHE_PROGRAM}' but it was not found in PATH."
|
||||||
|
CMAKE_CCACHE=""
|
||||||
|
}
|
||||||
|
elif command -v sccache >/dev/null 2>&1 ; then
|
||||||
|
CMAKE_CCACHE=$(command -v sccache)
|
||||||
|
elif command -v ccache >/dev/null 2>&1 ; then
|
||||||
|
CMAKE_CCACHE=$(command -v ccache)
|
||||||
|
fi
|
||||||
|
if [ -n "${CMAKE_CCACHE}" ] ; then
|
||||||
|
echo "${CMAKE_CCACHE} found, enabling compiler caching..."
|
||||||
|
CMAKE_CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_CCACHE}" -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CCACHE}")
|
||||||
|
# The same ccache settings as the CI build. Without this sloppiness ccache refuses every
|
||||||
|
# compile that uses the precompiled header, which is most of OrcaSlicer, and skips headers
|
||||||
|
# a checkout has just written. It is added to the sloppiness already configured, and
|
||||||
|
# CCACHE_SLOPPINESS or CCACHE_(NO)DEPEND set in the environment win.
|
||||||
|
if [[ "$(basename "${CMAKE_CCACHE}")" == ccache ]] ; then
|
||||||
|
if [[ -z "${CCACHE_SLOPPINESS+x}" ]] ; then
|
||||||
|
CCACHE_SLOPPINESS=$("${CMAKE_CCACHE}" --get-config sloppiness 2>/dev/null || true)
|
||||||
|
export CCACHE_SLOPPINESS="${CCACHE_SLOPPINESS:+${CCACHE_SLOPPINESS},}pch_defines,time_macros,include_file_mtime,include_file_ctime"
|
||||||
|
fi
|
||||||
|
# Hash the includes the compiler reports instead of preprocessing every miss.
|
||||||
|
if [[ -z "${CCACHE_DEPEND+x}${CCACHE_NODEPEND+x}" ]] ; then
|
||||||
|
export CCACHE_DEPEND=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Note: ccache or sccache are not found. Install either of them for faster rebuilds."
|
||||||
|
# Clear a launcher recorded by an earlier configure. The entries must be set empty rather
|
||||||
|
# than removed: CMake fills a missing launcher entry from the environment.
|
||||||
|
CMAKE_CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER:STRING= -DCMAKE_CXX_COMPILER_LAUNCHER:STRING=)
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Build params:"
|
echo "Build params:"
|
||||||
echo " - ARCH: $ARCH"
|
echo " - ARCH: $ARCH"
|
||||||
echo " - BUILD_CONFIG: $BUILD_CONFIG"
|
echo " - BUILD_CONFIG: $BUILD_CONFIG"
|
||||||
@@ -162,7 +230,9 @@ function build_deps() {
|
|||||||
-DCMAKE_OSX_ARCHITECTURES:STRING="${_ARCH}" \
|
-DCMAKE_OSX_ARCHITECTURES:STRING="${_ARCH}" \
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
|
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
|
||||||
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
|
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
|
||||||
${CMAKE_POLICY_COMPAT}
|
"${CMAKE_CCACHE_ARGS[@]}" \
|
||||||
|
${CMAKE_POLICY_COMPAT} \
|
||||||
|
"${EXTRA_CMAKE_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
cmake --build . --config "$BUILD_CONFIG" --target deps
|
cmake --build . --config "$BUILD_CONFIG" --target deps
|
||||||
)
|
)
|
||||||
@@ -264,7 +334,9 @@ function build_slicer() {
|
|||||||
-DCMAKE_OSX_ARCHITECTURES="${_ARCH}" \
|
-DCMAKE_OSX_ARCHITECTURES="${_ARCH}" \
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
|
-DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \
|
||||||
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
|
-DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \
|
||||||
${CMAKE_POLICY_COMPAT}
|
"${CMAKE_CCACHE_ARGS[@]}" \
|
||||||
|
${CMAKE_POLICY_COMPAT} \
|
||||||
|
"${EXTRA_CMAKE_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
|
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
|
||||||
)
|
)
|
||||||
|
|||||||
+7
-4
@@ -53,7 +53,7 @@ call :add_section "Build configuration"
|
|||||||
call :add_arg config string "" config "release, debug, relwithdebinfo or minsizerel (default: release)"
|
call :add_arg config string "" config "release, debug, relwithdebinfo or minsizerel (default: release)"
|
||||||
call :add_arg target_arch string "" arch "x64 or arm64 (default: the host architecture)"
|
call :add_arg target_arch string "" arch "x64 or arm64 (default: the host architecture)"
|
||||||
call :add_arg slicer_asan bool a asan "Build the slicer with ASAN enabled"
|
call :add_arg slicer_asan bool a asan "Build the slicer with ASAN enabled"
|
||||||
call :add_arg no_pch bool "" no-pch "Build without the precompiled header, implied by --cache"
|
call :add_arg no_pch bool "" no-pch "Build without the precompiled header, implied by -l and --cache"
|
||||||
|
|
||||||
call :add_section "Toolchain"
|
call :add_section "Toolchain"
|
||||||
call :add_arg use_clang_cl bool l clang-cl "Use clang-cl as the compiler"
|
call :add_arg use_clang_cl bool l clang-cl "Use clang-cl as the compiler"
|
||||||
@@ -388,6 +388,9 @@ if "%use_ninja%" == "ON" if "%use_msbuild%" == "ON" (
|
|||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
REM CMakeLists turns the precompiled header off for clang-cl (llvm/llvm-project#53486).
|
||||||
|
if "%use_clang_cl%" == "ON" set "no_pch=ON"
|
||||||
|
|
||||||
set "generator=!vs_gen_%vs_version%!"
|
set "generator=!vs_gen_%vs_version%!"
|
||||||
if "%use_ninja%" == "ON" (
|
if "%use_ninja%" == "ON" (
|
||||||
set "generator=Ninja Multi-Config"
|
set "generator=Ninja Multi-Config"
|
||||||
@@ -543,7 +546,7 @@ REM real path rather than one glued onto the repository root.
|
|||||||
for %%p in ("!build_dir!") do set "build_full=%%~fp"
|
for %%p in ("!build_dir!") do set "build_full=%%~fp"
|
||||||
echo Configuration: %build_type%, %arch%
|
echo Configuration: %build_type%, %arch%
|
||||||
if not "%clang_exe%" == "" echo Compiler: %clang_exe%
|
if not "%clang_exe%" == "" echo Compiler: %clang_exe%
|
||||||
if "%no_pch%" == "ON" echo Precompiled header: off
|
if "%build_slicer%" == "ON" if "%no_pch%" == "ON" echo Precompiled header: off
|
||||||
if not "%cache_args%" == "" echo Compiler cache: %cache_exe%
|
if not "%cache_args%" == "" echo Compiler cache: %cache_exe%
|
||||||
|
|
||||||
set "SIG_FLAG="
|
set "SIG_FLAG="
|
||||||
@@ -716,8 +719,8 @@ if "%build_slicer%" == "ON" (
|
|||||||
set "slicer_args=!slicer_args! -DSLIC3R_ASAN=ON"
|
set "slicer_args=!slicer_args! -DSLIC3R_ASAN=ON"
|
||||||
)
|
)
|
||||||
|
|
||||||
REM A later -DSLIC3R_PCH=ON in ORCA_SLICER_CMAKE_ARGS still wins, because
|
REM Under cl, a later -DSLIC3R_PCH=ON in ORCA_SLICER_CMAKE_ARGS still wins,
|
||||||
REM CMake takes the last definition on the command line.
|
REM because CMake takes the last definition on the command line.
|
||||||
if "%no_pch%" == "ON" (
|
if "%no_pch%" == "ON" (
|
||||||
set "slicer_args=!slicer_args! -DSLIC3R_PCH=OFF"
|
set "slicer_args=!slicer_args! -DSLIC3R_PCH=OFF"
|
||||||
)
|
)
|
||||||
|
|||||||
Vendored
+2
-17
@@ -1,22 +1,7 @@
|
|||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
if (JPEG_VERSION STREQUAL "6")
|
|
||||||
message("Using Jpeg Lib 62")
|
|
||||||
set(jpeg_flag "")
|
|
||||||
elseif (JPEG_VERSION STREQUAL "7")
|
|
||||||
message("Using Jpeg Lib 70")
|
|
||||||
set(jpeg_flag "-DWITH_JPEG7=ON")
|
|
||||||
else ()
|
|
||||||
message("Using Jpeg Lib 80")
|
|
||||||
set(jpeg_flag "-DWITH_JPEG8=ON")
|
|
||||||
endif ()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
orcaslicer_add_cmake_project(JPEG
|
orcaslicer_add_cmake_project(JPEG
|
||||||
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.0.1.zip
|
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.2.0.zip
|
||||||
URL_HASH SHA256=d6d99e693366bc03897677650e8b2dfa76b5d6c54e2c9e70c03f0af821b0a52f
|
URL_HASH SHA256=1b4c2cb6cba1ca5e53b9e85eeeab02154cab4b70894c96e97a9c747a26d19d63
|
||||||
DEPENDS ${ZLIB_PKG}
|
|
||||||
CMAKE_ARGS
|
CMAKE_ARGS
|
||||||
-DENABLE_SHARED=OFF
|
-DENABLE_SHARED=OFF
|
||||||
-DENABLE_STATIC=ON
|
-DENABLE_STATIC=ON
|
||||||
${jpeg_flag}
|
|
||||||
)
|
)
|
||||||
Vendored
+5
-2
@@ -26,6 +26,7 @@ orcaslicer_add_cmake_project(OpenCV
|
|||||||
URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz
|
URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz
|
||||||
URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
|
URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277
|
||||||
PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch
|
PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch
|
||||||
|
DEPENDS ${JPEG_PKG}
|
||||||
CMAKE_ARGS
|
CMAKE_ARGS
|
||||||
-DBUILD_SHARED_LIBS=0
|
-DBUILD_SHARED_LIBS=0
|
||||||
-DBUILD_PERE_TESTS=OFF
|
-DBUILD_PERE_TESTS=OFF
|
||||||
@@ -34,7 +35,8 @@ orcaslicer_add_cmake_project(OpenCV
|
|||||||
-DBUILD_EXAMPLES=OFF
|
-DBUILD_EXAMPLES=OFF
|
||||||
-DBUILD_JASPER=OFF
|
-DBUILD_JASPER=OFF
|
||||||
-DBUILD_JAVA=OFF
|
-DBUILD_JAVA=OFF
|
||||||
-DBUILD_JPEG=ON
|
# Share Orca's libjpeg to avoid conflicting codec symbols in the application.
|
||||||
|
-DBUILD_JPEG=OFF
|
||||||
-DBUILD_APPS_LIST=version
|
-DBUILD_APPS_LIST=version
|
||||||
-DBUILD_opencv_apps=OFF
|
-DBUILD_opencv_apps=OFF
|
||||||
-DBUILD_opencv_java=OFF
|
-DBUILD_opencv_java=OFF
|
||||||
@@ -67,7 +69,8 @@ orcaslicer_add_cmake_project(OpenCV
|
|||||||
-DWITH_OPENJPEG=OFF
|
-DWITH_OPENJPEG=OFF
|
||||||
-DWITH_QUIRC=OFF
|
-DWITH_QUIRC=OFF
|
||||||
-DWITH_VTK=OFF
|
-DWITH_VTK=OFF
|
||||||
-DWITH_JPEG=OFF
|
# Textured GLB/OBJ imports decode embedded and external JPEGs with cv::imdecode.
|
||||||
|
-DWITH_JPEG=ON
|
||||||
-DWITH_WEBP=OFF
|
-DWITH_WEBP=OFF
|
||||||
-DWITH_TIFF=OFF
|
-DWITH_TIFF=OFF
|
||||||
-DBUILD_TIFF=OFF
|
-DBUILD_TIFF=OFF
|
||||||
|
|||||||
Vendored
+17
-7
@@ -16,6 +16,8 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(_openssl_dir ${DESTDIR})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(_openssl_msvc_env CC=cl CXX=cl RC=rc CL=/FS)
|
set(_openssl_msvc_env CC=cl CXX=cl RC=rc CL=/FS)
|
||||||
# OpenSSL's perl Configure honors the CC environment variable, but the
|
# OpenSSL's perl Configure honors the CC environment variable, but the
|
||||||
@@ -43,6 +45,14 @@ if(WIN32)
|
|||||||
else()
|
else()
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
|
set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
|
||||||
|
# OPENSSLDIR is only where OpenSSL looks at runtime for cert.pem, certs/
|
||||||
|
# and openssl.cnf; install_sw installs nothing there. Point it at the
|
||||||
|
# system CA bundle, the one libcurl already uses here, so the bundled
|
||||||
|
# Python's ssl module can verify HTTPS. Elsewhere it stays the prefix:
|
||||||
|
# Windows Python reads the system certificate store, and on Linux, where
|
||||||
|
# the bundle's location differs by distro, CurlGlobalInit points
|
||||||
|
# SSL_CERT_FILE at it at startup.
|
||||||
|
set(_openssl_dir /etc/ssl)
|
||||||
else()
|
else()
|
||||||
# A static library that is embedded into a shared object must not export
|
# A static library that is embedded into a shared object must not export
|
||||||
# its symbols. On Linux the running process also loads the system OpenSSL
|
# its symbols. On Linux the running process also loads the system OpenSSL
|
||||||
@@ -81,7 +91,7 @@ ExternalProject_Add(dep_OpenSSL
|
|||||||
# URL_HASH SHA256=8c776993154652d0bb393f506d850b811517c8bd8d24b1008aef57fbe55d3f31
|
# URL_HASH SHA256=8c776993154652d0bb393f506d850b811517c8bd8d24b1008aef57fbe55d3f31
|
||||||
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/OpenSSL
|
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/OpenSSL
|
||||||
CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch}
|
CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch}
|
||||||
"--openssldir=${DESTDIR}"
|
"--openssldir=${_openssl_dir}"
|
||||||
"--prefix=${DESTDIR}"
|
"--prefix=${DESTDIR}"
|
||||||
# OpenSSL's linux-x86_64 target sets multilib=64, so it installs to
|
# OpenSSL's linux-x86_64 target sets multilib=64, so it installs to
|
||||||
# <prefix>/lib64 while every other dep uses <prefix>/lib. CPython's
|
# <prefix>/lib64 while every other dep uses <prefix>/lib. CPython's
|
||||||
@@ -115,12 +125,12 @@ ExternalProject_Add_Step(dep_OpenSSL install_cmake_files
|
|||||||
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
|
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
if (NOT WIN32)
|
||||||
# OpenSSL's object rules do not depend on CFLAGS, so reconfiguring it (for
|
# OpenSSL's object rules do not depend on the configured flags or paths, so
|
||||||
# example to add -fvisibility=hidden) relinks the archives from stale
|
# reconfiguring it (a new compiler flag, a different --openssldir) relinks
|
||||||
# objects instead of recompiling them, and the change silently has no
|
# the archives from stale objects instead of recompiling them, and the
|
||||||
# effect. Drop the objects whenever this recipe changes so the next build
|
# change silently has no effect. Drop the objects whenever this recipe
|
||||||
# actually recompiles them.
|
# changes so the next build actually recompiles them.
|
||||||
ExternalProject_Get_Property(dep_OpenSSL SOURCE_DIR)
|
ExternalProject_Get_Property(dep_OpenSSL SOURCE_DIR)
|
||||||
ExternalProject_Add_Step(dep_OpenSSL clean_objects
|
ExternalProject_Add_Step(dep_OpenSSL clean_objects
|
||||||
DEPENDEES configure
|
DEPENDEES configure
|
||||||
|
|||||||
Vendored
+5
-4
@@ -365,10 +365,11 @@ if(TARGET dep_ZLIB)
|
|||||||
add_dependencies(dep_python3 dep_ZLIB)
|
add_dependencies(dep_python3 dep_ZLIB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
if (NOT WIN32)
|
||||||
# CPython's Makefile rules for _ssl and _hashlib depend only on their own
|
# _ssl and _hashlib embed the static OpenSSL built in deps/ (Windows uses
|
||||||
# sources, not on the OpenSSL archives, so a rebuilt OpenSSL does not make
|
# CPython's prebuilt OpenSSL instead). Their Makefile rules depend only on
|
||||||
# them relink and they keep the previous symbols. On an incremental tree,
|
# their own sources, not on the OpenSSL archives, so a rebuilt OpenSSL does
|
||||||
|
# not make them relink and they keep the previous one. On an incremental tree,
|
||||||
# drop the built modules and relink them against the current OpenSSL; a
|
# drop the built modules and relink them against the current OpenSSL; a
|
||||||
# fresh build is left alone (its PGO target builds them). "make" alone is a
|
# fresh build is left alone (its PGO target builds them). "make" alone is a
|
||||||
# no-op once PGO has run, so sharedmods is invoked explicitly.
|
# no-op once PGO has run, so sharedmods is invoked explicitly.
|
||||||
|
|||||||
Vendored
+9
-1
@@ -21,6 +21,14 @@ else ()
|
|||||||
set(_wx_edge "-DwxUSE_WEBVIEW_EDGE=OFF")
|
set(_wx_edge "-DwxUSE_WEBVIEW_EDGE=OFF")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# With a precompiled header, clang-cl can omit an exception type's copy constructor from its throw info,
|
||||||
|
# so copies of the exception share and double-free their data: https://github.com/llvm/llvm-project/issues/53486
|
||||||
|
if (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set(_wx_precomp OFF)
|
||||||
|
else ()
|
||||||
|
set(_wx_precomp ON)
|
||||||
|
endif ()
|
||||||
|
|
||||||
set(_wx_patch_command "")
|
set(_wx_patch_command "")
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(_wx_patch_command
|
set(_wx_patch_command
|
||||||
@@ -39,7 +47,7 @@ orcaslicer_add_cmake_project(
|
|||||||
PATCH_COMMAND ${_wx_patch_command}
|
PATCH_COMMAND ${_wx_patch_command}
|
||||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG}
|
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG}
|
||||||
CMAKE_ARGS
|
CMAKE_ARGS
|
||||||
-DwxBUILD_PRECOMP=ON
|
-DwxBUILD_PRECOMP=${_wx_precomp}
|
||||||
${_wx_toolkit}
|
${_wx_toolkit}
|
||||||
"-DCMAKE_DEBUG_POSTFIX:STRING=${_wx_debug_postfix}"
|
"-DCMAKE_DEBUG_POSTFIX:STRING=${_wx_debug_postfix}"
|
||||||
-DwxBUILD_DEBUG_LEVEL=0
|
-DwxBUILD_DEBUG_LEVEL=0
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Adaptive TPMS infill — High Level Design
|
# Adaptive infill — High Level Design
|
||||||
|
|
||||||
## Purpose and scope
|
## Purpose and scope
|
||||||
|
|
||||||
`tpms_adaptive` grades the sparse infill of the Gyroid, TPMS-D and TPMS-FK
|
`adaptive_infill_mode` grades the sparse infill of the Gyroid, TPMS-D and TPMS-FK
|
||||||
patterns inside the object: the cells grow continuously from the surface
|
patterns inside the object: the cells grow continuously from the surface
|
||||||
towards the center of the object. `distance_warp`, `smooth_blend` and
|
towards the center of the object. `distance_warp`, `smooth_blend` and
|
||||||
`stepped_shells` follow the distance to the nearest surface, including the top
|
`stepped_shells` follow the distance to the nearest surface, including the top
|
||||||
@@ -10,8 +10,8 @@ and bottom, like concentric shells; `lobes` follows the whole 3D shape towards
|
|||||||
the center of each lobe of the object; `normal_z`, `normal_y` and `normal_x`
|
the center of each lobe of the object; `normal_z`, `normal_y` and `normal_x`
|
||||||
follow each section of the object normal to that axis, so the grading does not
|
follow each section of the object normal to that axis, so the grading does not
|
||||||
change along the axis, as suits a profile extruded along it.
|
change along the axis, as suits a profile extruded along it.
|
||||||
`sparse_infill_density` is the density at the surface, `tpms_interior_density`
|
`sparse_infill_density` is the density at the surface, `adaptive_infill_interior_density`
|
||||||
the density at the center, and `tpms_adaptive_gradient` picks how the density
|
the density at the center, and `adaptive_infill_gradient` picks how the density
|
||||||
goes from one to the other. Only internal sparse infill is graded; the Gyroid
|
goes from one to the other. Only internal sparse infill is graded; the Gyroid
|
||||||
Z-buckling optimization does not apply to it.
|
Z-buckling optimization does not apply to it.
|
||||||
|
|
||||||
@@ -22,9 +22,9 @@ split into shells or blended between densities.
|
|||||||
|
|
||||||
## Radial field
|
## Radial field
|
||||||
|
|
||||||
`TpmsRadialField` gives every point of an object the center of its lobe and a
|
`AdaptiveInfillField` gives every point of an object the center of its lobe and a
|
||||||
radial coordinate: 0 at the center, 1 at the surface along the ray from the
|
radial coordinate: 0 at the center, 1 at the surface along the ray from the
|
||||||
center. `PrintObject::prepare_tpms_radial_fields()` builds it in
|
center. `PrintObject::prepare_adaptive_infill_fields()` builds it in
|
||||||
`bridge_over_infill()`, next to the adaptive cubic octree, because the anchoring
|
`bridge_over_infill()`, next to the adaptive cubic octree, because the anchoring
|
||||||
infill generated there has to match the printed infill. A field is built for
|
infill generated there has to match the printed infill. A field is built for
|
||||||
every mode a region uses, and is shared by the regions using that mode: the
|
every mode a region uses, and is shared by the regions using that mode: the
|
||||||
@@ -202,7 +202,7 @@ built for them.
|
|||||||
|
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
- With `tpms_adaptive` disabled, or for other patterns, the fill parameters are reset
|
- With `adaptive_infill_mode` disabled, or for other patterns, the fill parameters are reset
|
||||||
to their defaults, so they neither change the infill nor split fill batches.
|
to their defaults, so they neither change the infill nor split fill batches.
|
||||||
- `Layer::get_sparse_infill_max_void_area()` uses the sparser of the two
|
- `Layer::get_sparse_infill_max_void_area()` uses the sparser of the two
|
||||||
densities, as the voids at the center are that large.
|
densities, as the voids at the center are that large.
|
||||||
@@ -350,8 +350,11 @@ identity default and translates nothing. `NetworkAgent` forwards both to the liv
|
|||||||
comparison sites below reach them through `wxGetApp().getAgent()` and leave an id untranslated
|
comparison sites below reach them through `wxGetApp().getAgent()` and leave an id untranslated
|
||||||
while no agent is live. Whole documents are Bambu's business alone:
|
while no agent is live. Whole documents are Bambu's business alone:
|
||||||
`BBLPrinterAgent::to_orca_payload` and `from_orca_payload` rewrite every string under
|
`BBLPrinterAgent::to_orca_payload` and `from_orca_payload` rewrite every string under
|
||||||
`tray_info_idx`, `filament_id` or `filamentId` at any depth; text that does not parse, or carries
|
`tray_info_idx`, `filament_id`, `filamentId`, `cate` or `fila_id` at any depth; text that does not
|
||||||
none of those keys, comes back unchanged. The map is loaded once, lazily; a missing or malformed
|
parse, or carries none of those keys, comes back unchanged. The last two are the H2C nozzle rack's:
|
||||||
|
`cate` in the auto nozzle mapping request, `fila_id` in the rack status. A new Bambu message that
|
||||||
|
carries a filament id under another key needs that key added to `filament_id_keys`, or the id
|
||||||
|
crosses the boundary untranslated. The map is loaded once, lazily; a missing or malformed
|
||||||
file degrades to identity with a log line rather than failing.
|
file degrades to identity with a log line rather than failing.
|
||||||
|
|
||||||
| Boundary | Where it translates |
|
| Boundary | Where it translates |
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ Space counts as typing. The speed dial's default is the one bare Space, and
|
|||||||
`MainFrame` leaves it to a focused control that uses Space itself (text fields, buttons,
|
`MainFrame` leaves it to a focused control that uses Space itself (text fields, buttons,
|
||||||
combo boxes), so it opens the dial from the canvases and the tab strip only.
|
combo boxes), so it opens the dial from the canvases and the tab strip only.
|
||||||
|
|
||||||
|
`MainFrame::handle_global_shortcut` skips a chord that `KeyChord::edits_text()` reports
|
||||||
|
while a text field has the focus (a wx text entry, spin control, web view or ImGui
|
||||||
|
InputText), and skips every chord while an ImGui modal is open, as a wx modal dialog
|
||||||
|
would. `ImGuiWrapper::owns_key()` reads the active InputText and the popup stack
|
||||||
|
directly, since `WantCaptureKeyboard` lags a frame, and is called only when the focus is on
|
||||||
|
a visible canvas from `OpenGLManager::create_wxglcanvas()`.
|
||||||
|
|
||||||
## Which event a chord matches
|
## Which event a chord matches
|
||||||
|
|
||||||
Letters, digits and special keys match on `wxEVT_KEY_DOWN`. Its key codes do not depend
|
Letters, digits and special keys match on `wxEVT_KEY_DOWN`. Its key codes do not depend
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
# Travel optimization — High Level Design
|
||||||
|
|
||||||
|
## Purpose and scope
|
||||||
|
|
||||||
|
Inside an island, the infill paths of each region are chained into one print
|
||||||
|
order by a greedy pass that joins the closest free path ends first. That pass
|
||||||
|
leaves its longest joins for last, and they often cross the whole island. Two
|
||||||
|
things shorten the travel between infill paths:
|
||||||
|
|
||||||
|
- the fill generators join their lines into as few paths as they can, since
|
||||||
|
every separate path needs a travel to it;
|
||||||
|
- the G-code export refines the greedy chain with a local search that shortens
|
||||||
|
the straight-line travel between the paths.
|
||||||
|
|
||||||
|
The refinement covers every chain that `chain_and_reorder_extrusion_entities()`
|
||||||
|
builds from a start point: the infill and ironing of `GCode::extrude_infill()`
|
||||||
|
and the support of `GCode::extrude_support()`, as well as the order of objects
|
||||||
|
and islands under `print_order` Default. It changes only the order and the
|
||||||
|
direction of the paths, not the paths or the walls. Neither part has a setting.
|
||||||
|
|
||||||
|
## The chain
|
||||||
|
|
||||||
|
`ObjectByExtruder::Island::Region::append()` flattens every sortable fill
|
||||||
|
collection into its paths, so the paths of all the fills of a region in one
|
||||||
|
island are chained together. A collection that must keep its order (`no_sort`:
|
||||||
|
monotonic, concentric, a forced fill order, the flow calibration) stays a single
|
||||||
|
entry that cannot be reversed. Paths that must keep their direction cannot be
|
||||||
|
reversed either: Grid's, since it alternates their direction between layers for
|
||||||
|
strength, and those of a fill with a forced order. A loop starts and ends at the
|
||||||
|
same point, so reversing it changes nothing.
|
||||||
|
|
||||||
|
`extrude_infill()` chains each region from the current nozzle position with
|
||||||
|
`chain_and_reorder_extrusion_entities()`, and chains the paths inside a nested
|
||||||
|
sortable collection the same way; `extrude_support()` chains the support paths
|
||||||
|
of a layer so too, unless they keep their order. The overload without a start
|
||||||
|
point, used to chain collections while slicing, keeps the greedy chain. The
|
||||||
|
order the fill generators give their paths does not reach the G-code for a
|
||||||
|
sortable fill, which is chained again.
|
||||||
|
|
||||||
|
## Connecting the lines
|
||||||
|
|
||||||
|
Most patterns cut their lines at the infill boundary, and `Fill::connect_infill()`
|
||||||
|
joins pairs of line ends that are neighbors on a boundary contour by the arc of
|
||||||
|
wall between them, shortest arcs first, as long as neither end is joined yet and
|
||||||
|
the join closes no loop. An arc is joined when it is shorter than
|
||||||
|
`infill_anchor_max`, or than two anchors and a line width if that is longer:
|
||||||
|
two ends further apart each get an anchor toward the other, and where those
|
||||||
|
would meet, the join prints about as much wall as one path instead of two.
|
||||||
|
|
||||||
|
Regular patterns leave many arcs of the same length, and the order among them
|
||||||
|
decides the pairing. In an arbitrary order the pairs along one wall can fall out
|
||||||
|
of step, such as lines 1–2 and 3–4, then 6–7 and 8–9, which leaves the end of
|
||||||
|
line 5 loose, and every loose end starts or ends a separate path. So the arcs
|
||||||
|
are also sorted in steps of half the line spacing and, within a step, along each
|
||||||
|
contour forwards and backwards, which pairs the ends of a wall in one phase.
|
||||||
|
Each order is replayed on the flags and a union-find of the lines, without
|
||||||
|
building any path, and the one that joins the most lines is used; a tie keeps
|
||||||
|
the shortest-first order.
|
||||||
|
|
||||||
|
The replay includes the last pass, which joins any two open ends that are
|
||||||
|
neighbors on a contour. With multiline infill the main pass leaves the copies of
|
||||||
|
one line to that pass, so that each copy reaches a wall of its own. Two
|
||||||
|
neighboring groups cut at both walls can then be joined at either wall by arcs
|
||||||
|
of the same length: at one, their open ends stay next to their own copies, which
|
||||||
|
the last pass joins, so each line prints out and back; at the other, the copies
|
||||||
|
end up in separate paths printed apart.
|
||||||
|
|
||||||
|
A line end left unpaired gets an anchor, a piece of the wall at most
|
||||||
|
`infill_anchor` long. It runs toward the nearest open end of another path,
|
||||||
|
looking up to 64 ends along the contour, since the next path usually starts
|
||||||
|
there; without one it takes the side with more free wall. With multiline infill
|
||||||
|
an anchor toward a copy of the same line stops short of the copy rather than
|
||||||
|
printing over it. A copy is a neighboring end less than the group width
|
||||||
|
(`multiline` spacings) across the line, at any wall angle, while the next group
|
||||||
|
lies a whole line spacing away. Meeting the wall at an angle θ, the copy covers
|
||||||
|
half a width over sin θ of the wall on each side of its end, so the anchor stops
|
||||||
|
that far and half its own width before it, or is left out; the end still counts
|
||||||
|
as anchored, so the last pass pairs the other ends as before.
|
||||||
|
|
||||||
|
Last, `Fill::fill_surface_extrusion()` joins the sparse infill lines whose ends
|
||||||
|
are at most two line spacings apart with a straight piece. With the anchors off
|
||||||
|
(`infill_anchor_max` 0) nothing above runs and this is the only joining; with
|
||||||
|
them on, it takes what the steps above leave next to each other, such as two
|
||||||
|
anchors that stop just short of each other or a short piece cut off by a corner.
|
||||||
|
A gap that short leaves no room to print anything in between, and as a travel it
|
||||||
|
is the one hop a reordering can trade for a longer travel that retracts.
|
||||||
|
Multiline copies leave the most such ends: one spacing apart across the line,
|
||||||
|
their ends where it meets a wall at an angle θ are one spacing over sin θ apart
|
||||||
|
along it, so two spacings reach walls met at 30° and steeper.
|
||||||
|
|
||||||
|
Ends that meet are joined first, then the gaps between the leading ends of their
|
||||||
|
lines, along each line's overall direction, then the rest, shortest first within
|
||||||
|
each, without closing a loop or crossing a line or another join. Taking the
|
||||||
|
leading ends first joins every pair of copies at the same side, which leaves
|
||||||
|
their open ends next to each other; by length alone, neighboring pairs were
|
||||||
|
joined at different walls and the travel between them crossed the island. Lines
|
||||||
|
that cannot reverse, such as Grid's, only join the end of one to the start of the
|
||||||
|
next, and fills that keep their order are left alone.
|
||||||
|
|
||||||
|
## The search
|
||||||
|
|
||||||
|
A chain of up to eight paths is found exactly, by dynamic programming over the
|
||||||
|
subsets of paths: a state is the paths visited so far, the last one and its
|
||||||
|
direction, about four thousand states for eight paths. The shared greedy
|
||||||
|
chaining, `chain_segments_greedy_constrained_reversals_()`, does the same for two
|
||||||
|
to four segments, which also orders up to four islands of a layer and the loops
|
||||||
|
of a perimeter collection exactly. Either way the first path is no longer
|
||||||
|
always the one nearest the start; with a free end, a path near the start can be
|
||||||
|
worth leaving for last.
|
||||||
|
|
||||||
|
Objects (`print_order` Default) and the tour of islands across objects are
|
||||||
|
visited in the same order on every layer, so `chain_points_with_postprocessing()`
|
||||||
|
orders them as a closed tour rather than an open chain. Up to ten points the
|
||||||
|
shortest tour is found exactly by the same dynamic programming with the first
|
||||||
|
point fixed; with a start point the tour then begins at the point nearest it.
|
||||||
|
Larger sets take the greedy chain and alternate 2-opt, or-opt and crossing
|
||||||
|
removal; or-opt moves runs of up to three points next to one of the eight points
|
||||||
|
nearest an end of the run, found on the same grid as the chain's candidates.
|
||||||
|
|
||||||
|
For longer chains, the search refines the greedy chain. On an island cut into many short pieces,
|
||||||
|
such as infill without anchors, that chain can sweep away from the nozzle and
|
||||||
|
come back for the rest with one long jump, which no local move below removes.
|
||||||
|
So a nearest-next chain, going from the nozzle to the nearest free path end each
|
||||||
|
time, is built too; when it is already shorter than the refined greedy chain, it
|
||||||
|
is refined and used instead. Elsewhere it costs one grid query per path.
|
||||||
|
|
||||||
|
`improve_chain_by_local_search()` sees the chain as a sequence of segments with
|
||||||
|
an entry and an exit point each. Its cost is the straight distance from the
|
||||||
|
nozzle to the first entry plus the distance from every exit to the next entry;
|
||||||
|
the end of the chain is free. It applies three kinds of moves:
|
||||||
|
|
||||||
|
- 2-opt reverses a run of segments, which flips each of them and replaces the
|
||||||
|
two links at the ends of the run.
|
||||||
|
- Or-opt moves a run of up to three segments between two others, flipped or
|
||||||
|
not.
|
||||||
|
- A run of any length that starts or ends next to the nozzle moves to the front.
|
||||||
|
Local search can settle on a chain that starts with a block of paths far from
|
||||||
|
the nozzle while the paths next to it sit in the middle, and moving that block
|
||||||
|
takes more than three segments at once.
|
||||||
|
|
||||||
|
A move that would flip a segment that cannot be reversed is skipped, so such
|
||||||
|
segments are only reordered.
|
||||||
|
|
||||||
|
A move is tried only if every link it creates joins an end point to one of the
|
||||||
|
32 end points nearest to it, which covers every move on a chain of up to 17
|
||||||
|
segments, as most islands are; with 8 candidates the search missed most of the
|
||||||
|
gain on grid-like patterns such as Triangles. The candidates come from a uniform
|
||||||
|
grid of about two end points per cell, searched in rings of cells around the
|
||||||
|
query. `KDTreeIndirect` visits its subtrees in a fixed order rather than the
|
||||||
|
nearer one first, so a query for 32 points walks most of the tree, and on long
|
||||||
|
chains finding the candidates would cost more than the search itself.
|
||||||
|
|
||||||
|
The candidates of an end point are tried nearest first, and only while they are
|
||||||
|
closer to it than the link the move would replace there. A 2-opt move that pays
|
||||||
|
off creates a link shorter than the one it replaces at one of its two ends, so
|
||||||
|
this misses no 2-opt move. An or-opt move is tried only while its new link is
|
||||||
|
shorter than what taking the run out saves, which skips a few or-opt moves that
|
||||||
|
would still pay off but cuts the search on long chains to a fraction.
|
||||||
|
|
||||||
|
The search works through a queue of segments and applies the first move that
|
||||||
|
shortens the chain around the segment it examines. After a move, only the
|
||||||
|
segments next to a changed link are queued again. A new link can also make room
|
||||||
|
for a run elsewhere that no segment next to it would try, so when the queue
|
||||||
|
empties after any move, every segment is queued once more, and the search ends
|
||||||
|
when such a sweep finds no move.
|
||||||
|
|
||||||
|
Every move shortens the chain by more than `SCALED_EPSILON`, so the result is
|
||||||
|
never longer than the greedy or the nearest-next chain and the search ends; a
|
||||||
|
cap of 50 moves per segment only bounds its time. The search has no randomness
|
||||||
|
and visits the segments in a fixed order, so the same input always gives the
|
||||||
|
same G-code.
|
||||||
|
|
||||||
|
## Cost
|
||||||
|
|
||||||
|
Finding the candidates of an end point visits a few cells, and the nearest-next
|
||||||
|
chain makes one such query per path, which only grows where the paths around the
|
||||||
|
nozzle are used up and the chain jumps. Examining a segment tries at most a few
|
||||||
|
hundred candidate links, usually only the nearest few, plus a scan of the chain
|
||||||
|
for the move to the front when it is the first segment, and a move rewrites only
|
||||||
|
the range of the chain it changes, so the search stays close to linear in the
|
||||||
|
number of segments. Most islands hold a few to a few dozen paths; the cost shows
|
||||||
|
on infill cut into thousands of pieces per island, such as dense infill with the
|
||||||
|
anchors off. The straight joins only look at the line segments near a candidate
|
||||||
|
join for crossings.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
The search minimizes straight-line distance. It does not know which travels
|
||||||
|
leave the infill area and retract under `reduce_infill_retraction`, nor the
|
||||||
|
detours of `reduce_crossing_wall`, and a travel's time is not proportional to
|
||||||
|
its length: a short travel is bound by acceleration, so its time grows about
|
||||||
|
with the square root of its length. A chain that is shorter in total but trades
|
||||||
|
very short travels for longer ones, or for ones past `retraction_minimum_travel`,
|
||||||
|
can occasionally take a little longer to print.
|
||||||
|
|
||||||
|
The end of the chain is free: it is not steered toward the next island or the
|
||||||
|
start of the next layer. The regions of an island are chained one after the
|
||||||
|
other, in region order, each from where the previous one ended.
|
||||||
+1384
-67
File diff suppressed because it is too large.
Load diff
+1872
-102
File diff suppressed because it is too large.
Load diff
+1877
-102
File diff suppressed because it is too large.
Load diff
+1877
-101
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1880
-102
File diff suppressed because it is too large.
Load diff
+1881
-105
File diff suppressed because it is too large.
Load diff
+1961
-181
File diff suppressed because it is too large.
Load diff
+1879
-104
File diff suppressed because it is too large.
Load diff
+1880
-101
File diff suppressed because it is too large.
Load diff
+1876
-102
File diff suppressed because it is too large.
Load diff
+1877
-103
File diff suppressed because it is too large.
Load diff
+1882
-102
File diff suppressed because it is too large.
Load diff
+1881
-103
File diff suppressed because it is too large.
Load diff
+1878
-102
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1887
-106
File diff suppressed because it is too large.
Load diff
+1880
-105
File diff suppressed because it is too large.
Load diff
+1869
-102
File diff suppressed because it is too large.
Load diff
+1884
-104
File diff suppressed because it is too large.
Load diff
+1883
-103
File diff suppressed because it is too large.
Load diff
+1871
-105
File diff suppressed because it is too large.
Load diff
+5017
-1941
File diff suppressed because it is too large.
Load diff
+6265
-2749
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><rect x="7" y="12" width="1" height="1" style="fill:#fefefe;"/><path d="M4.5,5.5c0-1.71,1.43-3.09,3.16-3,1.62.08,2.84,1.54,2.84,3.17h0c0,.61-.25,1.2-.69,1.62l-2.31,2.24v.97" style="fill:none; stroke:#fefefe; stroke-linecap:round; stroke-linejoin:round;"/></svg>
|
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><rect x="1.5" y="3.5" width="12" height="8" rx="1" ry="1" style="fill:none; stroke:#fefefe; stroke-linecap:round; stroke-linejoin:round;"/><path d="M3,5h1v1h-1Z M5,5h1v1h-1Z M7,5h1v1h-1Z M9,5h1v1h-1Z M11,5h1v1h-1Z M4,7h1v1h-1Z M6,7h1v1h-1Z M8,7h1v1h-1Z M10,7h1v1h-1Z M5,9h5v1h-5Z" style="fill:#fefefe;"/></svg>
|
||||||
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 415 B |
@@ -592,6 +592,10 @@
|
|||||||
"name": "SUNLU PETG @base",
|
"name": "SUNLU PETG @base",
|
||||||
"sub_path": "filament/SUNLU/SUNLU PETG @base.json"
|
"sub_path": "filament/SUNLU/SUNLU PETG @base.json"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "School House Spools PETG @base",
|
||||||
|
"sub_path": "filament/SchoolHouseSpools/School House Spools PETG @base.json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "eSUN PETG @base",
|
"name": "eSUN PETG @base",
|
||||||
"sub_path": "filament/eSUN/eSUN PETG @base.json"
|
"sub_path": "filament/eSUN/eSUN PETG @base.json"
|
||||||
@@ -1096,6 +1100,10 @@
|
|||||||
"name": "SUNLU Wood PLA @base",
|
"name": "SUNLU Wood PLA @base",
|
||||||
"sub_path": "filament/SUNLU/SUNLU Wood PLA @base.json"
|
"sub_path": "filament/SUNLU/SUNLU Wood PLA @base.json"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "School House Spools PLA @base",
|
||||||
|
"sub_path": "filament/SchoolHouseSpools/School House Spools PLA @base.json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Valment PLA @base",
|
"name": "Valment PLA @base",
|
||||||
"sub_path": "filament/Valment/Valment PLA @base.json"
|
"sub_path": "filament/Valment/Valment PLA @base.json"
|
||||||
@@ -2260,6 +2268,10 @@
|
|||||||
"name": "SUNLU PETG @System",
|
"name": "SUNLU PETG @System",
|
||||||
"sub_path": "filament/SUNLU/SUNLU PETG @System.json"
|
"sub_path": "filament/SUNLU/SUNLU PETG @System.json"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "School House Spools PETG @System",
|
||||||
|
"sub_path": "filament/SchoolHouseSpools/School House Spools PETG @System.json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "eSUN PETG @System",
|
"name": "eSUN PETG @System",
|
||||||
"sub_path": "filament/eSUN/eSUN PETG @System.json"
|
"sub_path": "filament/eSUN/eSUN PETG @System.json"
|
||||||
@@ -3812,6 +3824,10 @@
|
|||||||
"name": "SUNLU Wood PLA @System",
|
"name": "SUNLU Wood PLA @System",
|
||||||
"sub_path": "filament/SUNLU/SUNLU Wood PLA @System.json"
|
"sub_path": "filament/SUNLU/SUNLU Wood PLA @System.json"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "School House Spools PLA @System",
|
||||||
|
"sub_path": "filament/SchoolHouseSpools/School House Spools PLA @System.json"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Valment PLA @System",
|
"name": "Valment PLA @System",
|
||||||
"sub_path": "filament/Valment/Valment PLA @System.json"
|
"sub_path": "filament/Valment/Valment PLA @System.json"
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "School House Spools PETG @System",
|
||||||
|
"inherits": "School House Spools PETG @base",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "RSu2orfhR8ktT36h",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"13"
|
||||||
|
],
|
||||||
|
"filament_long_retractions_when_cut": [
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"filament_retraction_distances_when_cut": [
|
||||||
|
"18"
|
||||||
|
],
|
||||||
|
"compatible_printers": []
|
||||||
|
}
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "School House Spools PETG @base",
|
||||||
|
"inherits": "fdm_filament_pet",
|
||||||
|
"from": "system",
|
||||||
|
"filament_id": "OFnaCGQ9",
|
||||||
|
"instantiation": "false",
|
||||||
|
"cool_plate_temp": [
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"cool_plate_temp_initial_layer": [
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
"eng_plate_temp": [
|
||||||
|
"70"
|
||||||
|
],
|
||||||
|
"eng_plate_temp_initial_layer": [
|
||||||
|
"70"
|
||||||
|
],
|
||||||
|
"fan_cooling_layer_time": [
|
||||||
|
"30"
|
||||||
|
],
|
||||||
|
"fan_max_speed": [
|
||||||
|
"40"
|
||||||
|
],
|
||||||
|
"fan_min_speed": [
|
||||||
|
"10"
|
||||||
|
],
|
||||||
|
"filament_cost": [
|
||||||
|
"16.00"
|
||||||
|
],
|
||||||
|
"filament_density": [
|
||||||
|
"1.25"
|
||||||
|
],
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.95"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"8"
|
||||||
|
],
|
||||||
|
"filament_multitool_ramming_flow": [
|
||||||
|
"8"
|
||||||
|
],
|
||||||
|
"filament_vendor": [
|
||||||
|
"School House Spools"
|
||||||
|
],
|
||||||
|
"hot_plate_temp": [
|
||||||
|
"70"
|
||||||
|
],
|
||||||
|
"hot_plate_temp_initial_layer": [
|
||||||
|
"70"
|
||||||
|
],
|
||||||
|
"nozzle_temperature": [
|
||||||
|
"252"
|
||||||
|
],
|
||||||
|
"nozzle_temperature_initial_layer": [
|
||||||
|
"252"
|
||||||
|
],
|
||||||
|
"nozzle_temperature_range_high": [
|
||||||
|
"270"
|
||||||
|
],
|
||||||
|
"nozzle_temperature_range_low": [
|
||||||
|
"230"
|
||||||
|
],
|
||||||
|
"overhang_fan_speed": [
|
||||||
|
"90"
|
||||||
|
],
|
||||||
|
"overhang_fan_threshold": [
|
||||||
|
"10%"
|
||||||
|
],
|
||||||
|
"slow_down_layer_time": [
|
||||||
|
"12"
|
||||||
|
],
|
||||||
|
"textured_plate_temp": [
|
||||||
|
"70"
|
||||||
|
],
|
||||||
|
"textured_plate_temp_initial_layer": [
|
||||||
|
"70"
|
||||||
|
]
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "School House Spools PLA @System",
|
||||||
|
"inherits": "School House Spools PLA @base",
|
||||||
|
"from": "system",
|
||||||
|
"setting_id": "3rHJk6SVAvFzyHI0",
|
||||||
|
"instantiation": "true",
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"21"
|
||||||
|
],
|
||||||
|
"filament_long_retractions_when_cut": [
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"filament_retraction_distances_when_cut": [
|
||||||
|
"18"
|
||||||
|
],
|
||||||
|
"compatible_printers": []
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"type": "filament",
|
||||||
|
"name": "School House Spools PLA @base",
|
||||||
|
"inherits": "fdm_filament_pla",
|
||||||
|
"from": "system",
|
||||||
|
"filament_id": "OFHzwmT9",
|
||||||
|
"instantiation": "false",
|
||||||
|
"filament_cost": [
|
||||||
|
"17.00"
|
||||||
|
],
|
||||||
|
"filament_density": [
|
||||||
|
"1.26"
|
||||||
|
],
|
||||||
|
"filament_flow_ratio": [
|
||||||
|
"0.98"
|
||||||
|
],
|
||||||
|
"filament_max_volumetric_speed": [
|
||||||
|
"12"
|
||||||
|
],
|
||||||
|
"filament_vendor": [
|
||||||
|
"School House Spools"
|
||||||
|
],
|
||||||
|
"filament_scarf_seam_type": [
|
||||||
|
"none"
|
||||||
|
],
|
||||||
|
"filament_scarf_height": [
|
||||||
|
"10%"
|
||||||
|
],
|
||||||
|
"filament_scarf_gap": [
|
||||||
|
"0%"
|
||||||
|
],
|
||||||
|
"filament_scarf_length": [
|
||||||
|
"10"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "RatRig",
|
"name": "RatRig",
|
||||||
"version": "02.04.00.06",
|
"version": "02.04.00.07",
|
||||||
"force_update": "0",
|
"force_update": "0",
|
||||||
"description": "RatRig configurations",
|
"description": "RatRig configurations",
|
||||||
"machine_model_list": [
|
"machine_model_list": [
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
"z_hop": [
|
"z_hop": [
|
||||||
"0.2"
|
"0.2"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single] TOTAL_LAYER_COUNT={total_layer_count} X0={first_layer_print_min[0]} Y0={first_layer_print_min[1]} X1={first_layer_print_max[0]} Y1={first_layer_print_max[1]}",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n_ON_LAYER_CHANGE LAYER={layer_num + 1}",
|
||||||
"change_filament_gcode": "M600",
|
"change_filament_gcode": "M600",
|
||||||
|
|||||||
@@ -131,7 +131,7 @@
|
|||||||
"bed_exclude_area": [
|
"bed_exclude_area": [
|
||||||
"0x0"
|
"0x0"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single]",
|
"machine_start_gcode": "START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] EXTRUDER_OTHER_LAYER_TEMP=[nozzle_temperature] BED_TEMP=[bed_temperature_initial_layer_single]",
|
||||||
"machine_end_gcode": "END_PRINT",
|
"machine_end_gcode": "END_PRINT",
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
|
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Snapmaker",
|
"name": "Snapmaker",
|
||||||
"version": "02.04.00.17",
|
"version": "02.04.00.18",
|
||||||
"force_update": "0",
|
"force_update": "0",
|
||||||
"description": "Snapmaker configurations",
|
"description": "Snapmaker configurations",
|
||||||
"machine_model_list": [
|
"machine_model_list": [
|
||||||
|
|||||||
@@ -49,5 +49,8 @@
|
|||||||
],
|
],
|
||||||
"pressure_advance": [
|
"pressure_advance": [
|
||||||
"0.02"
|
"0.02"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"100"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -46,5 +46,8 @@
|
|||||||
],
|
],
|
||||||
"fan_min_speed": [
|
"fan_min_speed": [
|
||||||
"0"
|
"0"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"100"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"250"
|
"250"
|
||||||
],
|
],
|
||||||
"temperature_vitrification": [
|
"temperature_vitrification": [
|
||||||
"178"
|
"70"
|
||||||
],
|
],
|
||||||
"fan_max_speed": [
|
"fan_max_speed": [
|
||||||
"20"
|
"20"
|
||||||
|
|||||||
@@ -4,5 +4,8 @@
|
|||||||
"inherits": "fdm_filament_petg",
|
"inherits": "fdm_filament_petg",
|
||||||
"from": "system",
|
"from": "system",
|
||||||
"filament_id": "OFW8lqnb",
|
"filament_id": "OFW8lqnb",
|
||||||
"instantiation": "false"
|
"instantiation": "false",
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"70"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
"250"
|
"250"
|
||||||
],
|
],
|
||||||
"temperature_vitrification": [
|
"temperature_vitrification": [
|
||||||
"178"
|
"70"
|
||||||
],
|
],
|
||||||
"fan_max_speed": [
|
"fan_max_speed": [
|
||||||
"20"
|
"20"
|
||||||
|
|||||||
@@ -34,5 +34,8 @@
|
|||||||
],
|
],
|
||||||
"nozzle_temperature": [
|
"nozzle_temperature": [
|
||||||
"220"
|
"220"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"45"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -34,5 +34,8 @@
|
|||||||
],
|
],
|
||||||
"filament_cooling_final_speed": [
|
"filament_cooling_final_speed": [
|
||||||
"60"
|
"60"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"45"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -34,5 +34,8 @@
|
|||||||
],
|
],
|
||||||
"nozzle_temperature": [
|
"nozzle_temperature": [
|
||||||
"220"
|
"220"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"45"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -40,5 +40,8 @@
|
|||||||
],
|
],
|
||||||
"nozzle_temperature": [
|
"nozzle_temperature": [
|
||||||
"220"
|
"220"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"45"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -31,5 +31,8 @@
|
|||||||
],
|
],
|
||||||
"slow_down_layer_time": [
|
"slow_down_layer_time": [
|
||||||
"8"
|
"8"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"45"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -50,5 +50,8 @@
|
|||||||
"additional_cooling_fan_speed": [
|
"additional_cooling_fan_speed": [
|
||||||
"70",
|
"70",
|
||||||
"70"
|
"70"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"30"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
"240"
|
"240"
|
||||||
],
|
],
|
||||||
"temperature_vitrification": [
|
"temperature_vitrification": [
|
||||||
"60"
|
"30"
|
||||||
],
|
],
|
||||||
"nozzle_temperature_range_low": [
|
"nozzle_temperature_range_low": [
|
||||||
"200"
|
"200"
|
||||||
|
|||||||
@@ -302,7 +302,7 @@
|
|||||||
"-1"
|
"-1"
|
||||||
],
|
],
|
||||||
"temperature_vitrification": [
|
"temperature_vitrification": [
|
||||||
"60"
|
"30"
|
||||||
],
|
],
|
||||||
"textured_cool_plate_temp": [
|
"textured_cool_plate_temp": [
|
||||||
"40"
|
"40"
|
||||||
|
|||||||
@@ -29,5 +29,8 @@
|
|||||||
"additional_cooling_fan_speed": [
|
"additional_cooling_fan_speed": [
|
||||||
"70",
|
"70",
|
||||||
"70"
|
"70"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"30"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -49,5 +49,8 @@
|
|||||||
"additional_cooling_fan_speed": [
|
"additional_cooling_fan_speed": [
|
||||||
"70",
|
"70",
|
||||||
"70"
|
"70"
|
||||||
|
],
|
||||||
|
"temperature_vitrification": [
|
||||||
|
"30"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
"20",
|
"20",
|
||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n{endif} \n\n\n;===== 画起始线 =================\nG90\nG1 Z1.5\nG0 X85 Y1 Z2 F18000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG1 Z0.2\nM83\nG1 X185 E15 F360\nG1 Z1.5\n\nG90\nM106 S0",
|
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\n;===== top cover purifier =====\n{if min_vitrification_temperature <= 50}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=42 ALARM_TEMP=48 FAN_SPEED=0.6 DELAY_OFF=0 ; strong cooling\n{elsif min_vitrification_temperature <= 70}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=45 ALARM_TEMP=51 FAN_SPEED=0.6 DELAY_OFF=0 ; weak cooling\n{else}\nSET_PURIFIER_MODE MODE=3 DESIRE_TEMP=45 FAN_SPEED=0.6 DELAY_OFF=600 ; keep warm\n{endif}\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\n\n;==== 预挤出耗材 =====\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nT{initial_extruder}\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nSM_PRINT_PREEXTRUDE_FILAMENT INDEX={initial_extruder}\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nM107\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nM107\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nM106 S255\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\nM107\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\nM107\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; AlwLine truncated
|
||||||
"machine_tool_change_time": "5",
|
"machine_tool_change_time": "5",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.14",
|
"0.14",
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
"20",
|
"20",
|
||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n{endif} \n\n\n;===== 画起始线 =================\nG90\nG1 Z1.5\nG0 X85 Y1 Z2 F18000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG1 Z0.2\nM83\nG1 X185 E15 F360\nG1 Z1.5\n\nG90\nM106 S0",
|
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\n;===== top cover purifier =====\n{if min_vitrification_temperature <= 50}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=42 ALARM_TEMP=48 FAN_SPEED=0.6 DELAY_OFF=0 ; strong cooling\n{elsif min_vitrification_temperature <= 70}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=45 ALARM_TEMP=51 FAN_SPEED=0.6 DELAY_OFF=0 ; weak cooling\n{else}\nSET_PURIFIER_MODE MODE=3 DESIRE_TEMP=45 FAN_SPEED=0.6 DELAY_OFF=600 ; keep warm\n{endif}\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\n\n;==== 预挤出耗材 =====\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nT{initial_extruder}\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nSM_PRINT_PREEXTRUDE_FILAMENT INDEX={initial_extruder}\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nM107\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nM107\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nM106 S255\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\nM107\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\nM107\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; AlwLine truncated
|
||||||
"machine_tool_change_time": "5",
|
"machine_tool_change_time": "5",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.32",
|
"0.32",
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
"20",
|
"20",
|
||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n{endif} \n\n\n;===== 画起始线 =================\nG90\nG1 Z1.5\nG0 X85 Y1 Z2 F18000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG1 Z0.2\nM83\nG1 X185 E15 F360\nG1 Z1.5\n\nG90\nM106 S0",
|
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\n;===== top cover purifier =====\n{if min_vitrification_temperature <= 50}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=42 ALARM_TEMP=48 FAN_SPEED=0.6 DELAY_OFF=0 ; strong cooling\n{elsif min_vitrification_temperature <= 70}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=45 ALARM_TEMP=51 FAN_SPEED=0.6 DELAY_OFF=0 ; weak cooling\n{else}\nSET_PURIFIER_MODE MODE=3 DESIRE_TEMP=45 FAN_SPEED=0.6 DELAY_OFF=600 ; keep warm\n{endif}\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\n\n;==== 预挤出耗材 =====\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nT{initial_extruder}\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nSM_PRINT_PREEXTRUDE_FILAMENT INDEX={initial_extruder}\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nM107\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nM107\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nM106 S255\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\nM107\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\nM107\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; AlwLine truncated
|
||||||
"machine_tool_change_time": "5",
|
"machine_tool_change_time": "5",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.42",
|
"0.42",
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
"20",
|
"20",
|
||||||
"12"
|
"12"
|
||||||
],
|
],
|
||||||
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n{endif} \n\n\n;===== 画起始线 =================\nG90\nG1 Z1.5\nG0 X85 Y1 Z2 F18000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG1 Z0.2\nM83\nG1 X185 E15 F360\nG1 Z1.5\n\nG90\nM106 S0",
|
"machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20260128 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count} CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\n;===== top cover purifier =====\n{if min_vitrification_temperature <= 50}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=42 ALARM_TEMP=48 FAN_SPEED=0.6 DELAY_OFF=0 ; strong cooling\n{elsif min_vitrification_temperature <= 70}\nSET_PURIFIER_MODE MODE=1 DESIRE_TEMP=45 ALARM_TEMP=51 FAN_SPEED=0.6 DELAY_OFF=0 ; weak cooling\n{else}\nSET_PURIFIER_MODE MODE=3 DESIRE_TEMP=45 FAN_SPEED=0.6 DELAY_OFF=600 ; keep warm\n{endif}\nG28 X Y\nDEFECT_DETECT_NOODLE_FIRST\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\n\n;==== 预挤出耗材 =====\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nT{initial_extruder}\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder]}\nSM_PRINT_PREEXTRUDE_FILAMENT INDEX={initial_extruder}\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nM107\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nM107\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nM106 S255\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nWAIT_CHAMBER_TEMP TIMEOUT=180\nM107\n{if curr_bed_type==\"High Temp Plate\"} \nG28 Z Z_OFFSET -0.07 \n{else} \nG28 Z \n{endif} \n\n\n;===== 热床调平 =================\nM107\n{if curr_bed_type==\"High Temp Plate\"} \n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0 Z_OFFSET=-0.07\n{else} \n; AlwLine truncated
|
||||||
"machine_tool_change_time": "5",
|
"machine_tool_change_time": "5",
|
||||||
"max_layer_height": [
|
"max_layer_height": [
|
||||||
"0.56",
|
"0.56",
|
||||||
|
|||||||
Loaded 100 of 286 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user