Export the current 3D view as 2D DXF with optional hidden lines (#1449)

Adds File > Export > Current View as DXF: the visible bodies projected from the current camera onto 2D LINE/LWPOLYLINE entities, with hidden edges omitted or dashed.

Co-authored-by: cronos <19868002+crono2250@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-15 20:04:25 -04:00
1 parent 845f4913cf
commit c361630954
20 files changed
+798 -3

No files matched your search

+11
View File
@@ -258,6 +258,9 @@ pub enum Kind {
/// Surface tools and Split Face (`dialogs_surface`).
Surface(crate::dialogs_surface::Surf),
SaveMesh(crate::dialogs_save_mesh::SaveMesh),
ViewDxf {
dashed: bool,
},
/// Plastic features (`dialogs_plastic`).
Plastic(crate::dialogs_plastic::Pl),
/// Appearance (`dialogs_appearance`).
@@ -609,6 +612,7 @@ impl Dialog {
.or_else(|| crate::dialogs_sheet::start(app, id))
.or_else(|| crate::dialogs_surface::start(app, id))
.or_else(|| crate::dialogs_save_mesh::start(app, id))
.or_else(|| crate::dialogs_view_dxf::start(app, id))
.or_else(|| crate::dialogs_plastic::start(app, id))
.or_else(|| crate::dialogs_appearance::start(app, id))
.or_else(|| crate::dialogs_motion::start(app, id))
@@ -1379,6 +1383,7 @@ fn title(k: &Kind) -> &'static str {
Kind::Sheet(k) => k.title(),
Kind::Surface(k) => k.title(),
Kind::SaveMesh(_) => "SAVE AS MESH",
Kind::ViewDxf { .. } => "Export Current View as DXF",
Kind::Plastic(k) => k.title(),
Kind::Appearance(_) => "APPEARANCE",
Kind::Motion(k) => k.title(),
@@ -2773,6 +2778,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
Kind::Surface(k) => enter |= crate::dialogs_surface::rows(ui, k),
Kind::SketchModify(k) => enter |= crate::sketch_modify_ui::rows(ui, k),
Kind::SaveMesh(k) => enter |= crate::dialogs_save_mesh::rows(app, ui, k),
Kind::ViewDxf { dashed } => crate::dialogs_view_dxf::rows(app, ui, dashed),
Kind::Plastic(k) => enter |= crate::dialogs_plastic::rows(app, ui, k, &d.inputs),
Kind::Appearance(k) => enter |= crate::dialogs_appearance::rows(app, ui, k, &mut d.inputs),
Kind::Motion(k) => enter |= crate::dialogs_motion::rows(app, ui, k, &mut d.inputs),
@@ -2835,6 +2841,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
let raw_label = match &d.kind {
Kind::ConfirmDelete { .. } => "Delete",
Kind::SaveMesh(k) => crate::dialogs_save_mesh::button(k),
Kind::ViewDxf { .. } => "Export DXF…",
_ => "OK",
};
let label = tr(raw_label);
@@ -3278,6 +3285,9 @@ fn sels(d: &Dialog, i: usize) -> &[Sel] {
}
pub(crate) fn run_dialog(app: &mut SolveApp, d: &Dialog) -> Result<(), String> {
if let Kind::ViewDxf { dashed } = &d.kind {
return crate::dialogs_view_dxf::run(app, *dashed);
}
// Saving asks for a file name first; `Err("")` is the user backing out of that.
if let Kind::SaveMesh(k) = &d.kind {
return crate::dialogs_save_mesh::run(app, k, &d.inputs);
@@ -3975,6 +3985,7 @@ fn dialog_commands(app: &SolveApp, d: &Dialog) -> Result<Vec<(String, Value)>, S
Kind::Surface(k) => return crate::dialogs_surface::commands(app, k, &d.inputs, &d.extra),
Kind::SketchModify(k) => return crate::sketch_modify_ui::commands(app, k, &d.inputs, &d.extra),
Kind::SaveMesh(k) => return crate::dialogs_save_mesh::commands(k, &d.inputs),
Kind::ViewDxf { .. } => return Ok(Vec::new()),
Kind::Plastic(k) => return crate::dialogs_plastic::commands(app, k, &d.inputs, &d.extra),
Kind::Appearance(k) => return Ok(crate::dialogs_appearance::commands(k, &d.inputs)),
Kind::Motion(k) => return crate::dialogs_motion::commands(app, k, &d.inputs),