mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-03 00:42:46 -06:00
Save note: a DWG loses SAT-text solids from 2013 on, and the note says so (#2334)
A real DWG write and read-back keeps a SAT-text REGION's groups up to 2010 and returns it without them at 2013 and 2018, so the SAT-text skip in not_saved_as applies before 2013 only. The DWG note now says solids are kept in a DXF only when saved as 2010 or earlier.
This commit is contained in:
@@ -550,10 +550,10 @@ pub fn not_saved_as(d: &Drawing, version: Version) -> std::collections::BTreeMap
|
||||
let stores = std::iter::once(&d.model).chain(d.layouts.iter().map(|l| &l.entities)).chain(d.blocks.values().map(|b| &b.entities));
|
||||
for e in stores.flat_map(|s| s.iter()) {
|
||||
if let cadcraft_doc::EntityKind::Unknown(u) = &e.kind {
|
||||
// A DWG writer converts SAT text to its own form at any version, and from 2013 a data
|
||||
// store record keeps the geometry too: neither loses the solid.
|
||||
// A DWG before 2013 writes a solid's SAT text as it is; from 2013 the geometry has to be
|
||||
// in the data store, and SAT text alone is lost (#2334).
|
||||
if MODELER_TYPES.iter().any(|t| u.dxf_type.eq_ignore_ascii_case(t))
|
||||
&& (stored.contains(&e.handle) || cadcraft_doc::foreign::has_sat_text(&u.tags))
|
||||
&& (stored.contains(&e.handle) || (version < Version::R2013 && cadcraft_doc::foreign::has_sat_text(&u.tags)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -570,7 +570,10 @@ pub fn not_saved_message(lost: &std::collections::BTreeMap<String, usize>) -> Op
|
||||
return None;
|
||||
}
|
||||
let list: Vec<String> = lost.iter().map(|(t, n)| format!("{n} {t}")).collect();
|
||||
Some(format!("Not saved in the DWG file (its writer can't write these object types yet; DXF keeps them): {}", list.join(", ")))
|
||||
Some(format!(
|
||||
"Not saved in the DWG file (its writer can't write these object types yet; DXF keeps them, solids only when saved as 2010 or earlier): {}",
|
||||
list.join(", ")
|
||||
))
|
||||
}
|
||||
|
||||
/// Whether saving to `path` leaves out the entities [`not_saved`] counts: DWG does (the DWG
|
||||
|
||||
@@ -29,7 +29,7 @@ fn save_lists_the_entities_the_file_does_not_keep() {
|
||||
let r = s.execute("saveas", &json!({ "path": path.to_string_lossy() })).unwrap();
|
||||
let _ = std::fs::remove_file(&path);
|
||||
assert_eq!(r["notSaved"], json!({ "3DSOLID": 1, "MLINE": 2, "REGION": 1 }));
|
||||
let msg = "Not saved in the DWG file (its writer can't write these object types yet; DXF keeps them): 1 3DSOLID, 2 MLINE, 1 REGION";
|
||||
let msg = "Not saved in the DWG file (its writer can't write these object types yet; DXF keeps them, solids only when saved as 2010 or earlier): 1 3DSOLID, 2 MLINE, 1 REGION";
|
||||
assert!(s.log.iter().any(|l| l == msg), "{:?}", s.log);
|
||||
|
||||
// DXF keeps them.
|
||||
@@ -145,17 +145,17 @@ fn the_note_counts_the_host_drawing_while_a_block_is_edited() {
|
||||
assert_eq!(r["notSaved"], json!({ "REGION": 1 }));
|
||||
}
|
||||
|
||||
/// A DWG writer converts a solid's SAT text itself (at any version), so a DWG save doesn't list
|
||||
/// solids that hold it as left out; ones with neither SAT text nor a data store record are (#2334).
|
||||
/// A DWG before 2013 writes a solid's SAT text as it is, so a save there doesn't list a solid that
|
||||
/// holds it; from 2013 the geometry must be in the data store and SAT text alone is lost, so the
|
||||
/// save lists it. A solid with neither is always listed (#2334).
|
||||
#[test]
|
||||
fn a_dwg_keeps_solids_that_hold_sat_text() {
|
||||
fn a_dwg_keeps_sat_text_solids_only_before_2013() {
|
||||
use cadcraft_engine::cmd::file::{Version, not_saved_as};
|
||||
let tag = |code: i32, value: &str| RawTag { code, value: value.into() };
|
||||
let solid = |tags: Vec<RawTag>| EntityKind::Unknown(Unknown { dxf_type: "3DSOLID".into(), tags });
|
||||
let mut d = Drawing::new_imperial();
|
||||
d.add(&Space::Model, Common::default(), solid(vec![tag(100, "AcDbModelerGeometry"), tag(1, "400 1 1 0")])).unwrap();
|
||||
d.add(&Space::Model, Common::default(), solid(vec![tag(100, "AcDbModelerGeometry"), tag(70, "1")])).unwrap();
|
||||
for v in [Version::R2010, Version::R2018] {
|
||||
assert_eq!(not_saved_as(&d, v), [("3DSOLID".to_string(), 1)].into_iter().collect(), "{v:?}");
|
||||
}
|
||||
assert_eq!(not_saved_as(&d, Version::R2010), [("3DSOLID".to_string(), 1)].into_iter().collect(), "2010 keeps the SAT-text solid");
|
||||
assert_eq!(not_saved_as(&d, Version::R2018), [("3DSOLID".to_string(), 2)].into_iter().collect(), "2018 loses it");
|
||||
}
|
||||
|
||||
@@ -196,3 +196,24 @@ fn a_data_store_record_stores_only_its_first_entity() {
|
||||
let store = Foreign { data_store: vec![tag(0, "ACDSRECORD"), tag(320, "2B"), tag(320, "2C"), tag(2, "ASM_Data")], ..Foreign::default() };
|
||||
assert_eq!(store.data_store_entities(), [Handle(0x2B)].into());
|
||||
}
|
||||
|
||||
/// A real DWG round trip of a SAT-text REGION: the DWG writer keeps the SAT groups up to 2010, and
|
||||
/// from 2013 they come back empty (the solid's geometry is not in the file), which the DWG save
|
||||
/// note has to say (#2334).
|
||||
#[test]
|
||||
fn a_dwg_keeps_a_sat_text_region_only_before_2013() {
|
||||
let sat = "0\nSECTION\n2\nHEADER\n9\n$ACADVER\n1\nAC1015\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n\
|
||||
0\nREGION\n5\n2B\n100\nAcDbEntity\n8\n0\n100\nAcDbModelerGeometry\n70\n1\n1\n400 1 1 0\n3\nEnd-of-ACIS-data\n0\nENDSEC\n0\nEOF\n";
|
||||
let d = cadcraft_io::read_dxf(sat.as_bytes()).unwrap();
|
||||
let holds_sat = |v: cadcraft_io::Version| {
|
||||
let dwg = cadcraft_io::write_with(&d, "x.dwg", &cadcraft_io::SaveOptions { version: Some(v), binary: false }).unwrap();
|
||||
let back = cadcraft_io::read(&dwg, "x.dwg").unwrap();
|
||||
let region = back.model.iter().find_map(|e| match &e.kind {
|
||||
EntityKind::Unknown(u) if u.dxf_type == "REGION" => Some(u.clone()),
|
||||
_ => None,
|
||||
});
|
||||
region.is_some_and(|u| cadcraft_doc::foreign::has_sat_text(&u.tags))
|
||||
};
|
||||
assert!(holds_sat(cadcraft_io::Version::R2010), "2010 keeps the SAT text");
|
||||
assert!(!holds_sat(cadcraft_io::Version::R2018), "2018 comes back without it");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user