mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-09 03:50:04 -06:00
A proxy whose number names no class is left out of the DWG
dxf_to_dwg_as kept a proxy whose class number names no class of the DXF's CLASSES with that number, which names some other class of the DWG. It is now left out and counted, as a binary DXF's proxies are, and as CADCraft's own save already does.
This commit is contained in:
+17
-6
@@ -678,7 +678,8 @@ mod native {
|
||||
/// reader puts its own default classes first and numbers the DXF's after them, so the DXF
|
||||
/// number named another class in the DWG: a 2018 drawing's piping proxies became
|
||||
/// LARGE_RADIAL_DIMENSION and SECTIONOBJECT, and the ODA File Converter refused the file. A
|
||||
/// number that names no class of the DXF is left as it is.
|
||||
/// proxy whose number names no class of the DXF is left out: kept as it is, its number would
|
||||
/// name some other class of the DWG, for the same reason.
|
||||
///
|
||||
/// Before 2013 (AC1027) acadrust writes only the classes it knows a pre-2013 DWG needs, and a
|
||||
/// proxy's class is not one of them: the proxy would name a missing class (the ODA refuses
|
||||
@@ -715,24 +716,34 @@ mod native {
|
||||
let name = classes.get(usize::try_from(id.checked_sub(500)?).ok()?)?;
|
||||
doc.classes.get_by_name(name).map(|c| i32::from(c.class_number))
|
||||
};
|
||||
let objects: Vec<(acadrust::Handle, i32)> = doc
|
||||
let objects: Vec<(acadrust::Handle, Option<i32>)> = doc
|
||||
.objects
|
||||
.iter()
|
||||
.filter_map(|(h, o)| match o {
|
||||
acadrust::objects::ObjectType::ProxyObject(p) => number(p.class_id).map(|n| (*h, n)),
|
||||
acadrust::objects::ObjectType::ProxyObject(p) => Some((*h, number(p.class_id))),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
let entities: Vec<(acadrust::Handle, i32)> = doc
|
||||
let entities: Vec<(acadrust::Handle, Option<i32>)> = doc
|
||||
.entities()
|
||||
.filter_map(|e| match e {
|
||||
acadrust::entities::EntityType::Extended(x) => match &x.data {
|
||||
acadrust::entities::ExtendedEntityData::Proxy(p) => number(p.class_id).map(|n| (x.common.handle, n)),
|
||||
acadrust::entities::ExtendedEntityData::Proxy(p) => Some((x.common.handle, number(p.class_id))),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
let unmapped = |list: &[(acadrust::Handle, Option<i32>)]| list.iter().filter(|(_, n)| n.is_none()).map(|(h, _)| *h).collect::<Vec<_>>();
|
||||
let (gone_objects, gone_entities) = (unmapped(&objects), unmapped(&entities));
|
||||
for h in &gone_objects {
|
||||
doc.objects.remove(h);
|
||||
}
|
||||
for h in &gone_entities {
|
||||
doc.remove_entity(*h);
|
||||
}
|
||||
let objects = objects.into_iter().filter_map(|(h, n)| Some((h, n?)));
|
||||
let entities = entities.into_iter().filter_map(|(h, n)| Some((h, n?)));
|
||||
for (h, n) in objects {
|
||||
if let Some(acadrust::objects::ObjectType::ProxyObject(p)) = doc.objects.get_mut(&h) {
|
||||
p.class_id = n;
|
||||
@@ -747,7 +758,7 @@ mod native {
|
||||
}
|
||||
}
|
||||
}
|
||||
0
|
||||
gone_objects.len() + gone_entities.len()
|
||||
}
|
||||
|
||||
/// The current layer (`$CLAYER`) by its name, the same way as [`current_dimstyle`]: a DWG
|
||||
|
||||
@@ -2883,6 +2883,41 @@ fn proxies_keep_their_class_in_dwg() {
|
||||
}
|
||||
}
|
||||
|
||||
/// An ASCII DXF given to the DWG conversion directly, with a proxy whose number names no class of
|
||||
/// its CLASSES ([`proxy_file`]'s "Stray", 537): kept with that number it would name some other
|
||||
/// class of the DWG, so the DWG leaves it out, as CADCraft's own save does, and keeps the proxies
|
||||
/// whose classes it can name.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[test]
|
||||
fn a_proxy_whose_class_is_unknown_is_left_out_of_the_dwg() {
|
||||
use acadrust::entities::{EntityType, ExtendedEntityData};
|
||||
use acadrust::objects::ObjectType;
|
||||
let dwg = cadcraft_dwg::dxf_to_dwg_as(&proxy_file(), "AC1032").unwrap();
|
||||
let doc = acadrust::DwgReader::from_stream(std::io::Cursor::new(dwg)).read().unwrap();
|
||||
let class_of = |id: i32| doc.classes.iter().find(|c| i32::from(c.class_number) == id).map(|c| c.dxf_name.clone());
|
||||
let mut objects: Vec<Option<String>> = doc
|
||||
.objects
|
||||
.values()
|
||||
.filter_map(|o| match o {
|
||||
ObjectType::ProxyObject(p) => Some(class_of(p.class_id)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
objects.sort();
|
||||
assert_eq!(objects, [Some("VISUALSTYLE".to_string()), Some("WIDGETX".to_string())]);
|
||||
let entities: Vec<Option<String>> = doc
|
||||
.entities()
|
||||
.filter_map(|e| match e {
|
||||
EntityType::Extended(x) => match &x.data {
|
||||
ExtendedEntityData::Proxy(p) => Some(class_of(p.class_id)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(entities, [Some("WIDGETX".to_string())]);
|
||||
}
|
||||
|
||||
/// A binary DXF given to the DWG conversion directly: its CLASSES aren't read, so the proxies'
|
||||
/// numbers can't be mapped to the DWG's classes. Kept as they were, they named other classes
|
||||
/// (the ODA refuses such a file), so the DWG leaves them out, as a pre-2013 DWG does, and the
|
||||
|
||||
Reference in New Issue
Block a user