From 4a68f8428294730bad3777627ef3ad4866933a40 Mon Sep 17 00:00:00 2001 From: Osama Amin <341642285+osamaamin2011@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:30:48 +0300 Subject: [PATCH 1/2] DXF export: strokes as zero-width centerlines, a 3ds Max R12 linework preset, and one view direction in VPORT --- crates/cad/src/lib.rs | 3 +++ crates/cad/src/scene.rs | 22 +++++++++++++++++-- crates/cad/src/tests.rs | 21 ++++++++++++++++++ crates/cad/src/writer.rs | 3 ++- crates/engine/src/cmd/fileio/dxf.rs | 10 ++++++++- crates/ui-egui/src/dialogs/dxf_options.rs | 26 +++++++++++++++++++---- crates/ui-egui/src/i18n/cs.tsv | 3 +++ crates/ui-egui/src/i18n/de.tsv | 3 +++ crates/ui-egui/src/i18n/es.tsv | 3 +++ crates/ui-egui/src/i18n/fr.tsv | 3 +++ crates/ui-egui/src/i18n/hu.tsv | 4 ++++ crates/ui-egui/src/i18n/it.tsv | 3 +++ crates/ui-egui/src/i18n/ja.tsv | 3 +++ crates/ui-egui/src/i18n/ko.tsv | 3 +++ crates/ui-egui/src/i18n/pl.tsv | 3 +++ crates/ui-egui/src/i18n/pt-br.tsv | 1 + crates/ui-egui/src/i18n/ru.tsv | 3 +++ crates/ui-egui/src/i18n/uk.tsv | 3 +++ crates/ui-egui/src/i18n/vi.tsv | 4 ++++ crates/ui-egui/src/i18n/zh-hans.tsv | 3 +++ crates/ui-egui/src/i18n/zh-hant.tsv | 3 +++ docs/mcp.md | 8 +++++++ 22 files changed, 130 insertions(+), 8 deletions(-) diff --git a/crates/cad/src/lib.rs b/crates/cad/src/lib.rs index 4afe84e3..51bcd8c2 100644 --- a/crates/cad/src/lib.rs +++ b/crates/cad/src/lib.rs @@ -277,6 +277,8 @@ pub struct DxfOptions { pub colors: ColorDepth, pub raster: RasterFormat, pub preserve: Preserve, + /// Write one zero-width centerline per stroked path, ignoring its fill and stroke outline. + pub centerline_strokes: bool, /// Alter Paths for Appearance: every stroke is written as the filled area it paints. pub alter_paths: bool, /// Type is written as glyph outlines (always with [`Preserve::Appearance`]). @@ -297,6 +299,7 @@ impl Default for DxfOptions { colors: ColorDepth::default(), raster: RasterFormat::default(), preserve: Preserve::default(), + centerline_strokes: false, alter_paths: false, outline_text: false, region: Rect::ZERO, diff --git a/crates/cad/src/scene.rs b/crates/cad/src/scene.rs index 22fb1887..5cee1b50 100644 --- a/crates/cad/src/scene.rs +++ b/crates/cad/src/scene.rs @@ -457,21 +457,39 @@ impl<'a> Scene<'a> { if bp.elements().is_empty() { return; } + let centerline = self.o.centerline_strokes + && n.appearance + .items + .iter() + .any(|item| matches!(item, AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite())); + let mut wrote_centerline = false; for item in &n.appearance.items { match item { + AppearanceItem::Fill(_) if centerline => {} AppearanceItem::Fill(f) if f.visible => { if let Some(rgb) = self.paint_rgb(&f.paint) { let style = self.style(rgb, f.opacity, None, None); self.area(bp, rule, &style, false); } } - AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite() => self.stroke(bp, rule, st), + // One centerline per path, however many strokes it has. + AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite() && !(centerline && wrote_centerline) => { + self.stroke(bp, rule, st, centerline); + wrote_centerline |= centerline; + } _ => {} } } } - fn stroke(&mut self, bp: &BezPath, rule: FillRule, st: &StrokeLayer) { + fn stroke(&mut self, bp: &BezPath, rule: FillRule, st: &StrokeLayer, centerline: bool) { + if centerline { + let Some(rgb) = self.paint_rgb(&st.paint) else { return }; + let linetype = st.dash.as_ref().filter(|d| d.is_dashed()).map(|d| self.linetype(d)); + let style = self.style(rgb, st.opacity, Some(0.0), linetype); + self.lines(bp, &style, 0.0); + return; + } let appearance = self.o.preserve == Preserve::Appearance; if appearance && st.brush.is_some() diff --git a/crates/cad/src/tests.rs b/crates/cad/src/tests.rs index 996f6fba..37d1dbc8 100644 --- a/crates/cad/src/tests.rs +++ b/crates/cad/src/tests.rs @@ -125,6 +125,27 @@ fn every_version_declares_its_acadver_and_is_well_formed() { assert_eq!(DxfVersion::from_id("2019"), None); } +#[test] +fn r12_viewport_has_no_duplicate_group_codes() { + let d = shapes_doc(); + let out = export(&d, &DxfOptions { version: DxfVersion::R12, ..opts(&d) }).unwrap(); + let vport = table(&out, "VPORT").into_iter().find(|o| kind(o) == "VPORT").expect("VPORT table record"); + let codes: Vec = vport.iter().map(|pair| pair.0).collect(); + let unique: std::collections::HashSet<_> = codes.iter().collect(); + assert_eq!(unique.len(), codes.len(), "R12 VPORT record has duplicate group codes: {vport:?}"); + let z = vport.iter().find(|pair| pair.0 == 36).map(|pair| pair.1.trim().parse::().unwrap()); + assert_eq!(z, Some(1.0), "the view direction looks down the z axis"); +} + +#[test] +fn centerline_strokes_write_one_line_per_stroked_path_and_no_fill() { + let d = shapes_doc(); + let out = export(&d, &DxfOptions { centerline_strokes: true, ..opts(&d) }).unwrap(); + let k = kinds(&out); + assert!(k.iter().all(|kind| kind != "HATCH"), "the stroked rectangle's fill is left out: {k:?}"); + assert_eq!(k.len(), 2, "one centerline for each of the two stroked paths: {k:?}"); +} + #[test] fn lines_are_lwpolylines_curves_splines_and_fills_hatches() { let d = shapes_doc(); diff --git a/crates/cad/src/writer.rs b/crates/cad/src/writer.rs index 2fe4ec39..665f8576 100644 --- a/crates/cad/src/writer.rs +++ b/crates/cad/src/writer.rs @@ -441,7 +441,8 @@ impl Drawing { c.xy(13, 0.0, 0.0); c.xy(14, 1.0, 1.0); c.xy(15, 10.0, 10.0); - c.xyz(16, 0.0, 0.0); + // The view direction looks down the z axis: (0, 0, 1), each code once. + c.xy(16, 0.0, 0.0); c.num(36, 1.0); c.xyz(17, 0.0, 0.0); let (w, h) = ((x1 - x0).abs(), (y1 - y0).abs()); diff --git a/crates/engine/src/cmd/fileio/dxf.rs b/crates/engine/src/cmd/fileio/dxf.rs index c13b4fdb..30682760 100644 --- a/crates/engine/src/cmd/fileio/dxf.rs +++ b/crates/engine/src/cmd/fileio/dxf.rs @@ -21,7 +21,7 @@ pub fn specs() -> Vec { "Export DXF", [], None, - "{path?, version?: R12|R13|R14|2000|2004|2007|2010|2013|2018 (default), unit?: mm (default; any unit name: pt, in, cm…), scale?: 1 (drawing units per unit), scaleLineweights?: false, colors?: 8|16|256|true (default; true colour needs 2004+, else 256), rasterFormat?: png (default)|jpeg (placed images, written next to the file), preserve?: appearance (default: type as outlines; strokes a CAD line can't draw as filled outlines; brush art)|editability (type as text; every stroke a line with its lineweight and dashes), alterPaths?: false (every stroke as its filled outline), outlineText?: false, selectedOnly?: false (the selected objects, in their layers), artboard?: 0 (the origin is its bottom-left corner), useArtboards?: true (one drawing per chosen artboard, artboards?/range?, holding the art over it: {stem}-{artboard}.dxf) | false (the origin at the art's bounds)} → {path, bytes, warnings, files?, linked?: [image files]}; no path → {dataBase64, …, linked?: [{name, dataBase64}]}. Layers become DXF layers (hidden: off; locked; non-printing: not plotted); paths become polylines and splines, fills their outlines (which laser and cutter software reads) and solid hatches. Same as document.export {format: dxf}", + "{path?, version?: R12|R13|R14|2000|2004|2007|2010|2013|2018 (default), unit?: mm (default; any unit name: pt, in, cm…), scale?: 1 (drawing units per unit), scaleLineweights?: false, colors?: 8|16|256|true (default; true colour needs 2004+, else 256), rasterFormat?: png (default)|jpeg (placed images, written next to the file), preserve?: appearance (default: type as outlines; strokes a CAD line can't draw as filled outlines; brush art)|editability (type as text; every stroke a line with its lineweight and dashes), centerlineStrokes?: false (one zero-width centerline per stroked path; omits its fill), alterPaths?: false (every stroke as its filled outline), outlineText?: false, selectedOnly?: false (the selected objects, in their layers), artboard?: 0 (the origin is its bottom-left corner), useArtboards?: true (one drawing per chosen artboard, artboards?/range?, holding the art over it: {stem}-{artboard}.dxf) | false (the origin at the art's bounds)} → {path, bytes, warnings, files?, linked?: [image files]}; no path → {dataBase64, …, linked?: [{name, dataBase64}]}. Layers become DXF layers (hidden: off; locked; non-printing: not plotted); paths become polylines and splines, fills their outlines (which laser and cutter software reads) and solid hatches. Same as document.export {format: dxf}", has_doc, export_dxf )] @@ -60,6 +60,12 @@ pub(super) const OPTIONS: &[FormatOption] = &[ default: "\"appearance\"", description: "appearance (type as outlines, strokes a CAD line can't draw as filled outlines) or editability (type as text, strokes as lines)", }, + FormatOption { + name: "centerlineStrokes", + ty: "boolean", + default: "false", + description: "one zero-width centerline per stroked path; omits the path's fill and stroke outline", + }, FormatOption { name: "alterPaths", ty: "boolean", @@ -121,6 +127,7 @@ struct Params { colors: Option, raster_format: Option, preserve: Option, + centerline_strokes: Option, alter_paths: Option, outline_text: Option, } @@ -163,6 +170,7 @@ fn parse(p: &Value) -> Result<(DxfOptions, ArtboardPick)> { colors: choice("colors", q.colors.as_ref().map(text), ColorDepth::from_id, d.colors, "8, 16, 256 or true")?, raster: choice("rasterFormat", q.raster_format, RasterFormat::from_id, d.raster, "png or jpeg")?, preserve: choice("preserve", q.preserve, Preserve::from_id, d.preserve, "appearance or editability")?, + centerline_strokes: q.centerline_strokes.unwrap_or(d.centerline_strokes), alter_paths: q.alter_paths.unwrap_or(d.alter_paths), outline_text: q.outline_text.unwrap_or(d.outline_text), ..d diff --git a/crates/ui-egui/src/dialogs/dxf_options.rs b/crates/ui-egui/src/dialogs/dxf_options.rs index 3593dfe9..3ed3278d 100644 --- a/crates/ui-egui/src/dialogs/dxf_options.rs +++ b/crates/ui-egui/src/dialogs/dxf_options.rs @@ -1,6 +1,6 @@ //! DXF Options (Export As → DXF): version, scale (1 unit of the art = N drawing units) and //! lineweights, number of colours, the format of placed images, Preserve Appearance or Maximize -//! Editability, and Export Selected Art Only, Alter Paths for Appearance and Outline Text. +//! Editability, centerline stroke output, Export Selected Art Only, Alter Paths for Appearance and Outline Text. //! //! Fields: `document.export` params (`format: dxf`, `path?`, the artboard choice) and the DXF //! options of `document.exportDxf`. OK remembers the options for next time and writes the file @@ -42,6 +42,7 @@ fn defaults() -> Map { ("colors", json!(ColorDepth::default().id())), ("rasterFormat", json!(RasterFormat::default().id())), ("preserve", json!(Preserve::default().id())), + ("centerlineStrokes", json!(false)), ("alterPaths", json!(false)), ("outlineText", json!(false)), ("selectedOnly", json!(false)), @@ -65,6 +66,18 @@ pub fn open(app: &mut VectorcraftApp, params: &Value) { } fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { + if widgets::flat_button(ui, tl!("3ds Max — R12 Linework"), 210.0).clicked() { + d.fields.insert("version".into(), json!(DxfVersion::R12.id())); + d.fields.insert("unit".into(), json!(Unit::Millimeters.label())); + d.fields.insert("scale".into(), json!(1)); + d.fields.insert("preserve".into(), json!(Preserve::Editability.id())); + d.fields.insert("centerlineStrokes".into(), json!(true)); + d.fields.insert("colors".into(), json!(ColorDepth::Aci256.id())); + d.fields.insert("outlineText".into(), json!(true)); + d.fields.insert("alterPaths".into(), json!(false)); + d.fields.insert("scaleLineweights".into(), json!(false)); + } + ui.add_space(6.0); let versions: Vec<(&str, &str)> = DxfVersion::ALL.iter().map(|v| (v.id(), v.label())).collect(); choice(ui, d, "version", tl!("Version:"), &versions); ui.add_space(4.0); @@ -99,6 +112,7 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { d.fields.insert("selectedOnly".into(), json!(!d.bool("selectedOnly"))); } check(ui, d, "alterPaths", tl!("Alter Paths for Appearance")); + check(ui, d, "centerlineStrokes", tl!("Export Strokes as Centerlines (0 width)")); // Preserve Appearance always outlines type. let appearance = preserve == Preserve::Appearance; if widgets::check(ui, tl!("Outline Text"), appearance || d.bool("outlineText"), !appearance) { @@ -107,9 +121,13 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { ui.add_space(8.0); super::form::caption( ui, - match preserve { - Preserve::Appearance => tl!("Type becomes outlines, and strokes a CAD line can't draw become filled shapes."), - Preserve::Editability => tl!("Type stays text, and every stroke is a line with its lineweight and dashes."), + if d.bool("centerlineStrokes") { + tl!("Stroked paths become one zero-width centerline; their fills are omitted.") + } else { + match preserve { + Preserve::Appearance => tl!("Type becomes outlines, and strokes a CAD line can't draw become filled shapes."), + Preserve::Editability => tl!("Type stays text, and every stroke is a line with its lineweight and dashes."), + } }, ); false diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index ea273e44..8300a8c9 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -1906,6 +1906,9 @@ lighting Light Světlo Scale to Fit Artboard Přizpůsobit pracovní ploše Scaling Měřítko Alter Paths for Appearance Upravit cesty podle vzhledu + 3ds Max — R12 Linework Čárový výkres R12 pro 3ds Max + Export Strokes as Centerlines (0 width) Exportovat tahy jako osy (tloušťka 0) + Stroked paths become one zero-width centerline; their fills are omitted. Cesty s tahem se změní na jednu osu nulové tloušťky; jejich výplně se vynechají. DXF Options Možnosti DXF Export Option Možnost exportu Export Selected Art Only Exportovat jen vybranou kresbu diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index eb44f723..f076d495 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -147,6 +147,9 @@ Alt Alt Alt: Alt-Text: Alter Paths for Appearance Pfade für das Aussehen anpassen + 3ds Max — R12 Linework 3ds Max — R12-Linien + Export Strokes as Centerlines (0 width) Konturen als Mittellinien exportieren (Breite 0) + Stroked paths become one zero-width centerline; their fills are omitted. Pfade mit Kontur werden zu einer Mittellinie der Breite 0; ihre Flächen entfallen. Amount Stärke Amount: Stärke: Anchor Point Ankerpunkt diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 24652912..c39a51df 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -165,6 +165,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Modificar trazados según la apariencia + 3ds Max — R12 Linework Trazado lineal R12 para 3ds Max + Export Strokes as Centerlines (0 width) Exportar trazos como líneas centrales (grosor 0) + Stroked paths become one zero-width centerline; their fills are omitted. Los trazados con trazo se convierten en una línea central de grosor cero; se omiten sus rellenos. Amount Cantidad Amount: Cantidad: Anchor Point Punto de ancla diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 22e4f564..b8b7d045 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -166,6 +166,9 @@ Alt Alt Alt: Alt : Alter Paths for Appearance Modifier les tracés selon l’aspect + 3ds Max — R12 Linework 3ds Max — Tracé linéaire R12 + Export Strokes as Centerlines (0 width) Exporter les contours en lignes médianes (épaisseur 0) + Stroked paths become one zero-width centerline; their fills are omitted. Les tracés avec contour deviennent une ligne médiane d’épaisseur nulle ; leurs fonds sont omis. Amount Quantité Amount: Quantité : Anchor Point Point d’ancrage diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 6091a6c5..99e33129 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -252,6 +252,10 @@ Alt+Drag Alt+húzás Alt: Helyettesítő szöveg: Alter Paths for Appearance Útvonalak módosítása a megjelenés szerint + 3ds Max — R12 Linework 3ds Max — R12 vonalrajz + Export Strokes as Centerlines (0 width) Körvonalak exportálása középvonalként (0 vastagság) + Stroked paths become one zero-width centerline; their fills are omitted. A körvonalas útvonalakból egyetlen 0 vastagságú középvonal lesz; a kitöltésük elmarad. + Ambient Környezeti fény Amount Mérték Amount: Mérték: Analogous Analóg diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index aa9764b8..3a4aaba5 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -165,6 +165,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Modifica tracciati in base all'aspetto + 3ds Max — R12 Linework 3ds Max — Linee R12 + Export Strokes as Centerlines (0 width) Esporta tracce come linee d’asse (spessore 0) + Stroked paths become one zero-width centerline; their fills are omitted. I tracciati con traccia diventano un’unica linea d’asse a spessore zero; i riempimenti vengono omessi. Amount Quantità Amount: Quantità: Anchor Point Punto di ancoraggio diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index e2d291dc..4008debf 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -815,6 +815,9 @@ All the art すべてのアート Alt: 代替テキスト: Alter Paths for Appearance 外観を保つためにパスを変更 + 3ds Max — R12 Linework 3ds Max — R12 線画 + Export Strokes as Centerlines (0 width) 線を中心線として書き出し (幅 0) + Stroked paths become one zero-width centerline; their fills are omitted. 線のあるパスは幅 0 の中心線 1 本になり、塗りは省略されます。 Amount: 量: Anchor Point アンカーポイント Anchor Point Tool アンカーポイントツール diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index a643ab3b..f5666315 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -810,6 +810,9 @@ All the art 모든 아트워크 Alt: Alt: Alter Paths for Appearance 모양에 맞게 패스 변경 + 3ds Max — R12 Linework 3ds Max — R12 선 작업 + Export Strokes as Centerlines (0 width) 선을 중심선으로 내보내기(두께 0) + Stroked paths become one zero-width centerline; their fills are omitted. 선이 있는 패스는 두께 0인 중심선 하나가 되며 칠은 생략됩니다. Amount: 양: Anchor Point 앵커 포인트 Anchor Point Tool 앵커 포인트 도구 diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 57d42f66..df6ed6d9 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -1851,6 +1851,9 @@ lighting Light Światło Scale to Fit Artboard Skaluj, aby dopasować do obszaru kompozycji Scaling Skalowanie Alter Paths for Appearance Zmień ścieżki dla zachowania wyglądu + 3ds Max — R12 Linework 3ds Max — linie R12 + Export Strokes as Centerlines (0 width) Eksportuj obrysy jako linie środkowe (szerokość 0) + Stroked paths become one zero-width centerline; their fills are omitted. Ścieżki z obrysem stają się jedną linią środkową o zerowej szerokości; ich wypełnienia są pomijane. DXF Options Opcje DXF Export Option Opcja eksportu Export Selected Art Only Eksportuj tylko zaznaczoną kompozycję diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 75a81dca..68fc8948 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -175,6 +175,7 @@ All the art Toda a arte Alt: Alt: Alter Paths for Appearance Alterar Caminhos para Aparência + 3ds Max — R12 Linework Traçado em linhas R12 para 3ds Max Amount: Quantidade: Anchor Point Ponto de Ancoragem Anchor Point Tool Ferramenta Ponto de Ancoragem diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index d6e0c979..f7f03369 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -163,6 +163,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Изменять контуры для оформления + 3ds Max — R12 Linework 3ds Max — линии R12 + Export Strokes as Centerlines (0 width) Экспортировать обводки как осевые линии (толщина 0) + Stroked paths become one zero-width centerline; their fills are omitted. Контуры с обводкой становятся одной осевой линией нулевой толщины; заливки опускаются. Amount Количество Amount: Количество: Anchor Point Опорная точка diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index bc74406e..897684de 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -159,6 +159,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Змінювати контури для оформлення + 3ds Max — R12 Linework 3ds Max — лінії R12 + Export Strokes as Centerlines (0 width) Експортувати обведення як осьові лінії (товщина 0) + Stroked paths become one zero-width centerline; their fills are omitted. Контури з обведенням стають однією осьовою лінією нульової товщини; заливки пропускаються. Amount Кількість Amount: Кількість: Anchor Point Опорна точка diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 5792d956..98542231 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -191,6 +191,10 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Sửa đường dẫn cho diện mạo + 3ds Max — R12 Linework 3ds Max — đường nét R12 + Export Strokes as Centerlines (0 width) Xuất nét thành đường tâm (độ rộng 0) + Stroked paths become one zero-width centerline; their fills are omitted. Các đường có nét trở thành một đường tâm có độ rộng 0; phần tô của chúng bị bỏ qua. + Ambient Ánh sáng môi trường Amount Mức độ Amount: Mức độ: Anchor Point Điểm neo diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 105f571b..cdb84dff 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -125,6 +125,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance 为外观改变路径 + 3ds Max — R12 Linework 3ds Max — R12 线稿 + Export Strokes as Centerlines (0 width) 将描边导出为中心线(宽度 0) + Stroked paths become one zero-width centerline; their fills are omitted. 带描边的路径变为一条宽度为零的中心线;其填色将被省略。 Amount 数量 Amount: 数量: Anchor Point 锚点 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index 58ae4073..d880b61a 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -134,6 +134,9 @@ Alt Alt Alt: Alt: Alter Paths for Appearance 依外觀調整路徑 + 3ds Max — R12 Linework 3ds Max — R12 線稿 + Export Strokes as Centerlines (0 width) 將筆畫轉存為中心線 (寬度 0) + Stroked paths become one zero-width centerline; their fills are omitted. 具有筆畫的路徑會變成一條寬度為零的中心線;其填色不會保留。 Amount 數量 Amount: 數量: Anchor Point 錨點 diff --git a/docs/mcp.md b/docs/mcp.md index 9e67ca42..ccebe560 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -2277,6 +2277,14 @@ selected objects in their layers (every export takes it), and `useArtboards: tru artboard holding the art over it. What DXF can't hold (gradients and patterns as one colour, blending, opacity masks, raster effects, clipping) comes back in `warnings`. +`centerlineStrokes: true` writes each stroked path once, as a zero-width centerline (its fill and stroke outline +are left out): the linework 3D and CAM software extrude or sweep along, instead of the outline of the stroke's +width. For linework intended for 3ds Max, Export As → DXF has a **3ds Max — R12 Linework** preset: millimetres, R12 +polylines (curves are flattened), editable strokes as centerlines, 256 colours and outlined text, the version older +CAD importers read most reliably. Review the export warnings: R12 drops images and fill interiors. Through +`document.exportDxf` the preset is `version: "R12"`, `unit: "mm"`, `preserve: "editability"`, +`centerlineStrokes: true`, `colors: 256` and `outlineText: true`. + DWG can't be written (no openly licensed writer exists): `document.formats` lists it under `unsupported` with that hint, and exporting to it answers with the hint to export DXF. PICT files are not supported either and say so when opened. From a57aea8e940818e505ea85a62e6f91d7b080408e Mon Sep 17 00:00:00 2001 From: bflatastic Date: Wed, 14 Oct 2026 04:50:01 +0700 Subject: [PATCH 2/2] DXF export: leave out the centerline option and the 3ds Max preset for now The VPORT view direction fix and its test stay. The Export Strokes as Centerlines option and the preset button are not in the documented DXF/DWG export options, so they wait for the owner's decision. --- crates/cad/src/lib.rs | 3 --- crates/cad/src/scene.rs | 22 ++----------------- crates/cad/src/tests.rs | 9 -------- crates/engine/src/cmd/fileio/dxf.rs | 10 +-------- crates/ui-egui/src/dialogs/dxf_options.rs | 26 ++++------------------- crates/ui-egui/src/i18n/cs.tsv | 3 --- crates/ui-egui/src/i18n/de.tsv | 3 --- crates/ui-egui/src/i18n/es.tsv | 3 --- crates/ui-egui/src/i18n/fr.tsv | 3 --- crates/ui-egui/src/i18n/hu.tsv | 4 ---- crates/ui-egui/src/i18n/it.tsv | 3 --- crates/ui-egui/src/i18n/ja.tsv | 3 --- crates/ui-egui/src/i18n/ko.tsv | 3 --- crates/ui-egui/src/i18n/pl.tsv | 3 --- crates/ui-egui/src/i18n/pt-br.tsv | 1 - crates/ui-egui/src/i18n/ru.tsv | 3 --- crates/ui-egui/src/i18n/uk.tsv | 3 --- crates/ui-egui/src/i18n/vi.tsv | 4 ---- crates/ui-egui/src/i18n/zh-hans.tsv | 3 --- crates/ui-egui/src/i18n/zh-hant.tsv | 3 --- docs/mcp.md | 8 ------- 21 files changed, 7 insertions(+), 116 deletions(-) diff --git a/crates/cad/src/lib.rs b/crates/cad/src/lib.rs index 51bcd8c2..4afe84e3 100644 --- a/crates/cad/src/lib.rs +++ b/crates/cad/src/lib.rs @@ -277,8 +277,6 @@ pub struct DxfOptions { pub colors: ColorDepth, pub raster: RasterFormat, pub preserve: Preserve, - /// Write one zero-width centerline per stroked path, ignoring its fill and stroke outline. - pub centerline_strokes: bool, /// Alter Paths for Appearance: every stroke is written as the filled area it paints. pub alter_paths: bool, /// Type is written as glyph outlines (always with [`Preserve::Appearance`]). @@ -299,7 +297,6 @@ impl Default for DxfOptions { colors: ColorDepth::default(), raster: RasterFormat::default(), preserve: Preserve::default(), - centerline_strokes: false, alter_paths: false, outline_text: false, region: Rect::ZERO, diff --git a/crates/cad/src/scene.rs b/crates/cad/src/scene.rs index 5cee1b50..22fb1887 100644 --- a/crates/cad/src/scene.rs +++ b/crates/cad/src/scene.rs @@ -457,39 +457,21 @@ impl<'a> Scene<'a> { if bp.elements().is_empty() { return; } - let centerline = self.o.centerline_strokes - && n.appearance - .items - .iter() - .any(|item| matches!(item, AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite())); - let mut wrote_centerline = false; for item in &n.appearance.items { match item { - AppearanceItem::Fill(_) if centerline => {} AppearanceItem::Fill(f) if f.visible => { if let Some(rgb) = self.paint_rgb(&f.paint) { let style = self.style(rgb, f.opacity, None, None); self.area(bp, rule, &style, false); } } - // One centerline per path, however many strokes it has. - AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite() && !(centerline && wrote_centerline) => { - self.stroke(bp, rule, st, centerline); - wrote_centerline |= centerline; - } + AppearanceItem::Stroke(st) if st.visible && st.width > 0.0 && st.width.is_finite() => self.stroke(bp, rule, st), _ => {} } } } - fn stroke(&mut self, bp: &BezPath, rule: FillRule, st: &StrokeLayer, centerline: bool) { - if centerline { - let Some(rgb) = self.paint_rgb(&st.paint) else { return }; - let linetype = st.dash.as_ref().filter(|d| d.is_dashed()).map(|d| self.linetype(d)); - let style = self.style(rgb, st.opacity, Some(0.0), linetype); - self.lines(bp, &style, 0.0); - return; - } + fn stroke(&mut self, bp: &BezPath, rule: FillRule, st: &StrokeLayer) { let appearance = self.o.preserve == Preserve::Appearance; if appearance && st.brush.is_some() diff --git a/crates/cad/src/tests.rs b/crates/cad/src/tests.rs index 37d1dbc8..37bebbd0 100644 --- a/crates/cad/src/tests.rs +++ b/crates/cad/src/tests.rs @@ -137,15 +137,6 @@ fn r12_viewport_has_no_duplicate_group_codes() { assert_eq!(z, Some(1.0), "the view direction looks down the z axis"); } -#[test] -fn centerline_strokes_write_one_line_per_stroked_path_and_no_fill() { - let d = shapes_doc(); - let out = export(&d, &DxfOptions { centerline_strokes: true, ..opts(&d) }).unwrap(); - let k = kinds(&out); - assert!(k.iter().all(|kind| kind != "HATCH"), "the stroked rectangle's fill is left out: {k:?}"); - assert_eq!(k.len(), 2, "one centerline for each of the two stroked paths: {k:?}"); -} - #[test] fn lines_are_lwpolylines_curves_splines_and_fills_hatches() { let d = shapes_doc(); diff --git a/crates/engine/src/cmd/fileio/dxf.rs b/crates/engine/src/cmd/fileio/dxf.rs index 30682760..c13b4fdb 100644 --- a/crates/engine/src/cmd/fileio/dxf.rs +++ b/crates/engine/src/cmd/fileio/dxf.rs @@ -21,7 +21,7 @@ pub fn specs() -> Vec { "Export DXF", [], None, - "{path?, version?: R12|R13|R14|2000|2004|2007|2010|2013|2018 (default), unit?: mm (default; any unit name: pt, in, cm…), scale?: 1 (drawing units per unit), scaleLineweights?: false, colors?: 8|16|256|true (default; true colour needs 2004+, else 256), rasterFormat?: png (default)|jpeg (placed images, written next to the file), preserve?: appearance (default: type as outlines; strokes a CAD line can't draw as filled outlines; brush art)|editability (type as text; every stroke a line with its lineweight and dashes), centerlineStrokes?: false (one zero-width centerline per stroked path; omits its fill), alterPaths?: false (every stroke as its filled outline), outlineText?: false, selectedOnly?: false (the selected objects, in their layers), artboard?: 0 (the origin is its bottom-left corner), useArtboards?: true (one drawing per chosen artboard, artboards?/range?, holding the art over it: {stem}-{artboard}.dxf) | false (the origin at the art's bounds)} → {path, bytes, warnings, files?, linked?: [image files]}; no path → {dataBase64, …, linked?: [{name, dataBase64}]}. Layers become DXF layers (hidden: off; locked; non-printing: not plotted); paths become polylines and splines, fills their outlines (which laser and cutter software reads) and solid hatches. Same as document.export {format: dxf}", + "{path?, version?: R12|R13|R14|2000|2004|2007|2010|2013|2018 (default), unit?: mm (default; any unit name: pt, in, cm…), scale?: 1 (drawing units per unit), scaleLineweights?: false, colors?: 8|16|256|true (default; true colour needs 2004+, else 256), rasterFormat?: png (default)|jpeg (placed images, written next to the file), preserve?: appearance (default: type as outlines; strokes a CAD line can't draw as filled outlines; brush art)|editability (type as text; every stroke a line with its lineweight and dashes), alterPaths?: false (every stroke as its filled outline), outlineText?: false, selectedOnly?: false (the selected objects, in their layers), artboard?: 0 (the origin is its bottom-left corner), useArtboards?: true (one drawing per chosen artboard, artboards?/range?, holding the art over it: {stem}-{artboard}.dxf) | false (the origin at the art's bounds)} → {path, bytes, warnings, files?, linked?: [image files]}; no path → {dataBase64, …, linked?: [{name, dataBase64}]}. Layers become DXF layers (hidden: off; locked; non-printing: not plotted); paths become polylines and splines, fills their outlines (which laser and cutter software reads) and solid hatches. Same as document.export {format: dxf}", has_doc, export_dxf )] @@ -60,12 +60,6 @@ pub(super) const OPTIONS: &[FormatOption] = &[ default: "\"appearance\"", description: "appearance (type as outlines, strokes a CAD line can't draw as filled outlines) or editability (type as text, strokes as lines)", }, - FormatOption { - name: "centerlineStrokes", - ty: "boolean", - default: "false", - description: "one zero-width centerline per stroked path; omits the path's fill and stroke outline", - }, FormatOption { name: "alterPaths", ty: "boolean", @@ -127,7 +121,6 @@ struct Params { colors: Option, raster_format: Option, preserve: Option, - centerline_strokes: Option, alter_paths: Option, outline_text: Option, } @@ -170,7 +163,6 @@ fn parse(p: &Value) -> Result<(DxfOptions, ArtboardPick)> { colors: choice("colors", q.colors.as_ref().map(text), ColorDepth::from_id, d.colors, "8, 16, 256 or true")?, raster: choice("rasterFormat", q.raster_format, RasterFormat::from_id, d.raster, "png or jpeg")?, preserve: choice("preserve", q.preserve, Preserve::from_id, d.preserve, "appearance or editability")?, - centerline_strokes: q.centerline_strokes.unwrap_or(d.centerline_strokes), alter_paths: q.alter_paths.unwrap_or(d.alter_paths), outline_text: q.outline_text.unwrap_or(d.outline_text), ..d diff --git a/crates/ui-egui/src/dialogs/dxf_options.rs b/crates/ui-egui/src/dialogs/dxf_options.rs index 3ed3278d..3593dfe9 100644 --- a/crates/ui-egui/src/dialogs/dxf_options.rs +++ b/crates/ui-egui/src/dialogs/dxf_options.rs @@ -1,6 +1,6 @@ //! DXF Options (Export As → DXF): version, scale (1 unit of the art = N drawing units) and //! lineweights, number of colours, the format of placed images, Preserve Appearance or Maximize -//! Editability, centerline stroke output, Export Selected Art Only, Alter Paths for Appearance and Outline Text. +//! Editability, and Export Selected Art Only, Alter Paths for Appearance and Outline Text. //! //! Fields: `document.export` params (`format: dxf`, `path?`, the artboard choice) and the DXF //! options of `document.exportDxf`. OK remembers the options for next time and writes the file @@ -42,7 +42,6 @@ fn defaults() -> Map { ("colors", json!(ColorDepth::default().id())), ("rasterFormat", json!(RasterFormat::default().id())), ("preserve", json!(Preserve::default().id())), - ("centerlineStrokes", json!(false)), ("alterPaths", json!(false)), ("outlineText", json!(false)), ("selectedOnly", json!(false)), @@ -66,18 +65,6 @@ pub fn open(app: &mut VectorcraftApp, params: &Value) { } fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { - if widgets::flat_button(ui, tl!("3ds Max — R12 Linework"), 210.0).clicked() { - d.fields.insert("version".into(), json!(DxfVersion::R12.id())); - d.fields.insert("unit".into(), json!(Unit::Millimeters.label())); - d.fields.insert("scale".into(), json!(1)); - d.fields.insert("preserve".into(), json!(Preserve::Editability.id())); - d.fields.insert("centerlineStrokes".into(), json!(true)); - d.fields.insert("colors".into(), json!(ColorDepth::Aci256.id())); - d.fields.insert("outlineText".into(), json!(true)); - d.fields.insert("alterPaths".into(), json!(false)); - d.fields.insert("scaleLineweights".into(), json!(false)); - } - ui.add_space(6.0); let versions: Vec<(&str, &str)> = DxfVersion::ALL.iter().map(|v| (v.id(), v.label())).collect(); choice(ui, d, "version", tl!("Version:"), &versions); ui.add_space(4.0); @@ -112,7 +99,6 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { d.fields.insert("selectedOnly".into(), json!(!d.bool("selectedOnly"))); } check(ui, d, "alterPaths", tl!("Alter Paths for Appearance")); - check(ui, d, "centerlineStrokes", tl!("Export Strokes as Centerlines (0 width)")); // Preserve Appearance always outlines type. let appearance = preserve == Preserve::Appearance; if widgets::check(ui, tl!("Outline Text"), appearance || d.bool("outlineText"), !appearance) { @@ -121,13 +107,9 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool { ui.add_space(8.0); super::form::caption( ui, - if d.bool("centerlineStrokes") { - tl!("Stroked paths become one zero-width centerline; their fills are omitted.") - } else { - match preserve { - Preserve::Appearance => tl!("Type becomes outlines, and strokes a CAD line can't draw become filled shapes."), - Preserve::Editability => tl!("Type stays text, and every stroke is a line with its lineweight and dashes."), - } + match preserve { + Preserve::Appearance => tl!("Type becomes outlines, and strokes a CAD line can't draw become filled shapes."), + Preserve::Editability => tl!("Type stays text, and every stroke is a line with its lineweight and dashes."), }, ); false diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 8300a8c9..ea273e44 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -1906,9 +1906,6 @@ lighting Light Světlo Scale to Fit Artboard Přizpůsobit pracovní ploše Scaling Měřítko Alter Paths for Appearance Upravit cesty podle vzhledu - 3ds Max — R12 Linework Čárový výkres R12 pro 3ds Max - Export Strokes as Centerlines (0 width) Exportovat tahy jako osy (tloušťka 0) - Stroked paths become one zero-width centerline; their fills are omitted. Cesty s tahem se změní na jednu osu nulové tloušťky; jejich výplně se vynechají. DXF Options Možnosti DXF Export Option Možnost exportu Export Selected Art Only Exportovat jen vybranou kresbu diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index f076d495..eb44f723 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -147,9 +147,6 @@ Alt Alt Alt: Alt-Text: Alter Paths for Appearance Pfade für das Aussehen anpassen - 3ds Max — R12 Linework 3ds Max — R12-Linien - Export Strokes as Centerlines (0 width) Konturen als Mittellinien exportieren (Breite 0) - Stroked paths become one zero-width centerline; their fills are omitted. Pfade mit Kontur werden zu einer Mittellinie der Breite 0; ihre Flächen entfallen. Amount Stärke Amount: Stärke: Anchor Point Ankerpunkt diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index c39a51df..24652912 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -165,9 +165,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Modificar trazados según la apariencia - 3ds Max — R12 Linework Trazado lineal R12 para 3ds Max - Export Strokes as Centerlines (0 width) Exportar trazos como líneas centrales (grosor 0) - Stroked paths become one zero-width centerline; their fills are omitted. Los trazados con trazo se convierten en una línea central de grosor cero; se omiten sus rellenos. Amount Cantidad Amount: Cantidad: Anchor Point Punto de ancla diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index b8b7d045..22e4f564 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -166,9 +166,6 @@ Alt Alt Alt: Alt : Alter Paths for Appearance Modifier les tracés selon l’aspect - 3ds Max — R12 Linework 3ds Max — Tracé linéaire R12 - Export Strokes as Centerlines (0 width) Exporter les contours en lignes médianes (épaisseur 0) - Stroked paths become one zero-width centerline; their fills are omitted. Les tracés avec contour deviennent une ligne médiane d’épaisseur nulle ; leurs fonds sont omis. Amount Quantité Amount: Quantité : Anchor Point Point d’ancrage diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 99e33129..6091a6c5 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -252,10 +252,6 @@ Alt+Drag Alt+húzás Alt: Helyettesítő szöveg: Alter Paths for Appearance Útvonalak módosítása a megjelenés szerint - 3ds Max — R12 Linework 3ds Max — R12 vonalrajz - Export Strokes as Centerlines (0 width) Körvonalak exportálása középvonalként (0 vastagság) - Stroked paths become one zero-width centerline; their fills are omitted. A körvonalas útvonalakból egyetlen 0 vastagságú középvonal lesz; a kitöltésük elmarad. - Ambient Környezeti fény Amount Mérték Amount: Mérték: Analogous Analóg diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 3a4aaba5..aa9764b8 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -165,9 +165,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Modifica tracciati in base all'aspetto - 3ds Max — R12 Linework 3ds Max — Linee R12 - Export Strokes as Centerlines (0 width) Esporta tracce come linee d’asse (spessore 0) - Stroked paths become one zero-width centerline; their fills are omitted. I tracciati con traccia diventano un’unica linea d’asse a spessore zero; i riempimenti vengono omessi. Amount Quantità Amount: Quantità: Anchor Point Punto di ancoraggio diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 4008debf..e2d291dc 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -815,9 +815,6 @@ All the art すべてのアート Alt: 代替テキスト: Alter Paths for Appearance 外観を保つためにパスを変更 - 3ds Max — R12 Linework 3ds Max — R12 線画 - Export Strokes as Centerlines (0 width) 線を中心線として書き出し (幅 0) - Stroked paths become one zero-width centerline; their fills are omitted. 線のあるパスは幅 0 の中心線 1 本になり、塗りは省略されます。 Amount: 量: Anchor Point アンカーポイント Anchor Point Tool アンカーポイントツール diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index f5666315..a643ab3b 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -810,9 +810,6 @@ All the art 모든 아트워크 Alt: Alt: Alter Paths for Appearance 모양에 맞게 패스 변경 - 3ds Max — R12 Linework 3ds Max — R12 선 작업 - Export Strokes as Centerlines (0 width) 선을 중심선으로 내보내기(두께 0) - Stroked paths become one zero-width centerline; their fills are omitted. 선이 있는 패스는 두께 0인 중심선 하나가 되며 칠은 생략됩니다. Amount: 양: Anchor Point 앵커 포인트 Anchor Point Tool 앵커 포인트 도구 diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index df6ed6d9..57d42f66 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -1851,9 +1851,6 @@ lighting Light Światło Scale to Fit Artboard Skaluj, aby dopasować do obszaru kompozycji Scaling Skalowanie Alter Paths for Appearance Zmień ścieżki dla zachowania wyglądu - 3ds Max — R12 Linework 3ds Max — linie R12 - Export Strokes as Centerlines (0 width) Eksportuj obrysy jako linie środkowe (szerokość 0) - Stroked paths become one zero-width centerline; their fills are omitted. Ścieżki z obrysem stają się jedną linią środkową o zerowej szerokości; ich wypełnienia są pomijane. DXF Options Opcje DXF Export Option Opcja eksportu Export Selected Art Only Eksportuj tylko zaznaczoną kompozycję diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 68fc8948..75a81dca 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -175,7 +175,6 @@ All the art Toda a arte Alt: Alt: Alter Paths for Appearance Alterar Caminhos para Aparência - 3ds Max — R12 Linework Traçado em linhas R12 para 3ds Max Amount: Quantidade: Anchor Point Ponto de Ancoragem Anchor Point Tool Ferramenta Ponto de Ancoragem diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index f7f03369..d6e0c979 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -163,9 +163,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Изменять контуры для оформления - 3ds Max — R12 Linework 3ds Max — линии R12 - Export Strokes as Centerlines (0 width) Экспортировать обводки как осевые линии (толщина 0) - Stroked paths become one zero-width centerline; their fills are omitted. Контуры с обводкой становятся одной осевой линией нулевой толщины; заливки опускаются. Amount Количество Amount: Количество: Anchor Point Опорная точка diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 897684de..bc74406e 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -159,9 +159,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Змінювати контури для оформлення - 3ds Max — R12 Linework 3ds Max — лінії R12 - Export Strokes as Centerlines (0 width) Експортувати обведення як осьові лінії (товщина 0) - Stroked paths become one zero-width centerline; their fills are omitted. Контури з обведенням стають однією осьовою лінією нульової товщини; заливки пропускаються. Amount Кількість Amount: Кількість: Anchor Point Опорна точка diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 98542231..5792d956 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -191,10 +191,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance Sửa đường dẫn cho diện mạo - 3ds Max — R12 Linework 3ds Max — đường nét R12 - Export Strokes as Centerlines (0 width) Xuất nét thành đường tâm (độ rộng 0) - Stroked paths become one zero-width centerline; their fills are omitted. Các đường có nét trở thành một đường tâm có độ rộng 0; phần tô của chúng bị bỏ qua. - Ambient Ánh sáng môi trường Amount Mức độ Amount: Mức độ: Anchor Point Điểm neo diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index cdb84dff..105f571b 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -125,9 +125,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance 为外观改变路径 - 3ds Max — R12 Linework 3ds Max — R12 线稿 - Export Strokes as Centerlines (0 width) 将描边导出为中心线(宽度 0) - Stroked paths become one zero-width centerline; their fills are omitted. 带描边的路径变为一条宽度为零的中心线;其填色将被省略。 Amount 数量 Amount: 数量: Anchor Point 锚点 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index d880b61a..58ae4073 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -134,9 +134,6 @@ Alt Alt Alt: Alt: Alter Paths for Appearance 依外觀調整路徑 - 3ds Max — R12 Linework 3ds Max — R12 線稿 - Export Strokes as Centerlines (0 width) 將筆畫轉存為中心線 (寬度 0) - Stroked paths become one zero-width centerline; their fills are omitted. 具有筆畫的路徑會變成一條寬度為零的中心線;其填色不會保留。 Amount 數量 Amount: 數量: Anchor Point 錨點 diff --git a/docs/mcp.md b/docs/mcp.md index ccebe560..9e67ca42 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -2277,14 +2277,6 @@ selected objects in their layers (every export takes it), and `useArtboards: tru artboard holding the art over it. What DXF can't hold (gradients and patterns as one colour, blending, opacity masks, raster effects, clipping) comes back in `warnings`. -`centerlineStrokes: true` writes each stroked path once, as a zero-width centerline (its fill and stroke outline -are left out): the linework 3D and CAM software extrude or sweep along, instead of the outline of the stroke's -width. For linework intended for 3ds Max, Export As → DXF has a **3ds Max — R12 Linework** preset: millimetres, R12 -polylines (curves are flattened), editable strokes as centerlines, 256 colours and outlined text, the version older -CAD importers read most reliably. Review the export warnings: R12 drops images and fill interiors. Through -`document.exportDxf` the preset is `version: "R12"`, `unit: "mm"`, `preserve: "editability"`, -`centerlineStrokes: true`, `colors: 256` and `outlineText: true`. - DWG can't be written (no openly licensed writer exists): `document.formats` lists it under `unsupported` with that hint, and exporting to it answers with the hint to export DXF. PICT files are not supported either and say so when opened.