forked from 1b-agent/opencadstudio-upstream
refactor(dwg): use the first-class SectionSymbol and ViewBorder entities
Section marks and drawing-view borders are now real acadrust entity types instead of Unknown-with-extras, so the renderer dispatches on the variant directly, the arrow-direction resolver reads the active viewport off the ViewBorder entity, and selection / properties show "Section Symbol" and "View Border" instead of "Unknown". View borders are non-plotting and tessellate to nothing; both count toward the lossy Save-As warning since they round-trip via their raw records. Bumps acadrust for the entity promotion. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
3b2b8ad21d
commit
1cfb856224
7 files changed
+48
-29
No files matched your search
Generated
+1
-1
@@ -73,7 +73,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
||||
[[package]]
|
||||
name = "acadrust"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/OpenAEC-Foundation/acadifc?branch=main#8f2cf9543af65353c5fe3f7afbe5139de4ad711c"
|
||||
source = "git+https://github.com/OpenAEC-Foundation/acadifc?branch=main#6ddff17beca4413df1bad0d441eff9d6aaad298b"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"anyhow",
|
||||
|
||||
@@ -346,6 +346,8 @@ pub(super) fn entity_type_key(entity: &acadrust::EntityType) -> String {
|
||||
AttributeEntity(_) => "attrib",
|
||||
Ole2Frame(_) => "ole2frame",
|
||||
Light(_) => "light",
|
||||
SectionSymbol(_) => "sectionsymbol",
|
||||
ViewBorder(_) => "viewborder",
|
||||
Seqend(_) => "seqend",
|
||||
Unknown(_) => "unknown",
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ pub fn ui_name(e: &EntityType) -> &'static str {
|
||||
EntityType::AttributeEntity(_) => "Attribute",
|
||||
EntityType::Ole2Frame(_) => "OLE Frame",
|
||||
EntityType::Light(_) => "Light",
|
||||
EntityType::SectionSymbol(_) => "Section Symbol",
|
||||
EntityType::ViewBorder(_) => "View Border",
|
||||
EntityType::Seqend(_) => "Seqend",
|
||||
EntityType::Unknown(_) => "Unknown",
|
||||
}
|
||||
@@ -103,6 +105,8 @@ pub fn dxf_name(e: &EntityType) -> &'static str {
|
||||
EntityType::Surface(_) => "SURFACE",
|
||||
EntityType::Mesh(_) => "MESH",
|
||||
EntityType::Light(_) => "LIGHT",
|
||||
EntityType::SectionSymbol(_) => "SECTIONLINE",
|
||||
EntityType::ViewBorder(_) => "DRAWINGVIEW",
|
||||
_ => "ENTITY",
|
||||
}
|
||||
}
|
||||
@@ -143,6 +143,8 @@ pub fn entity_type_name(et: &EntityType) -> &'static str {
|
||||
EntityType::Ole2Frame(_) => "Ole2Frame",
|
||||
EntityType::PolygonMesh(_) => "PolygonMesh",
|
||||
EntityType::Light(_) => "Light",
|
||||
EntityType::SectionSymbol(_) => "SectionSymbol",
|
||||
EntityType::ViewBorder(_) => "ViewBorder",
|
||||
EntityType::Unknown(_) => "Unknown",
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -338,7 +338,12 @@ pub fn dropped_on_save_count(
|
||||
})
|
||||
.count();
|
||||
for e in doc.entities() {
|
||||
if matches!(e, acadrust::EntityType::Unknown(_)) {
|
||||
if matches!(
|
||||
e,
|
||||
acadrust::EntityType::Unknown(_)
|
||||
| acadrust::EntityType::SectionSymbol(_)
|
||||
| acadrust::EntityType::ViewBorder(_)
|
||||
) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -113,6 +113,8 @@ pub fn visualization_section(entity: &EntityType) -> Option<PropSection> {
|
||||
| EntityType::Seqend(_)
|
||||
| EntityType::Leader(_)
|
||||
| EntityType::Unknown(_)
|
||||
// Non-plotting drawing-view border: never rendered, no properties.
|
||||
| EntityType::ViewBorder(_)
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
|
||||
+31
-27
@@ -24,8 +24,8 @@ fn fade_if_locked(
|
||||
/// 2. The parent's refs name the section view's `AcDbViewRep` (any ref that
|
||||
/// owns an `AcDbViewRepSectionDefinition`), falling back to the document's
|
||||
/// section views.
|
||||
/// 3. Each view's refs include its `AcDbViewBorder`, whose first handle is the
|
||||
/// view's *active* viewport — the entity carrying the real camera.
|
||||
/// 3. Each view's refs include its `AcDbViewBorder` entity, which carries the
|
||||
/// view's *active* viewport — the entity holding the real camera.
|
||||
/// 4. The section camera's sight (−view_direction) is projected onto the parent
|
||||
/// camera's right/up basis (same convention as `camera_from_view`), giving
|
||||
/// the on-paper arrow direction.
|
||||
@@ -40,20 +40,23 @@ fn section_arrow_dir_from_views(
|
||||
if s.view_rep_handle == 0 {
|
||||
return None;
|
||||
}
|
||||
// A view's active viewport, via its border entity among the ViewRep refs.
|
||||
let border_vp = |h: &AHandle| -> Option<AHandle> {
|
||||
match document.get_entity(*h)? {
|
||||
EntityType::ViewBorder(b) if !b.active_viewport.is_null() => Some(b.active_viewport),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
let parent_vr = AHandle::from(s.view_rep_handle);
|
||||
let parent_refs = document.view_rep_refs.get(&parent_vr)?;
|
||||
let parent_vp_h = parent_refs
|
||||
.iter()
|
||||
.find_map(|h| document.view_border_viewport.get(h))?;
|
||||
let parent_vp_h = parent_refs.iter().find_map(border_vp)?;
|
||||
let sect_vr = parent_refs
|
||||
.iter()
|
||||
.find(|h| **h != parent_vr && document.section_view_reps.contains(h))
|
||||
.or_else(|| document.section_view_reps.iter().find(|&&h| h != parent_vr))
|
||||
.copied()?;
|
||||
let sect_refs = document.view_rep_refs.get(§_vr)?;
|
||||
let sect_vp_h = sect_refs
|
||||
.iter()
|
||||
.find_map(|h| document.view_border_viewport.get(h))?;
|
||||
let sect_vp_h = sect_refs.iter().find_map(border_vp)?;
|
||||
|
||||
let viewport = |h: &AHandle| {
|
||||
document.entities().find_map(|e| match e {
|
||||
@@ -61,8 +64,8 @@ fn section_arrow_dir_from_views(
|
||||
_ => None,
|
||||
})
|
||||
};
|
||||
let pvp = viewport(parent_vp_h)?;
|
||||
let svp = viewport(sect_vp_h)?;
|
||||
let pvp = viewport(&parent_vp_h)?;
|
||||
let svp = viewport(§_vp_h)?;
|
||||
|
||||
// Section sight: view_direction points target→camera, sight is its inverse.
|
||||
let sight = -glam::DVec3::new(
|
||||
@@ -606,23 +609,24 @@ pub(crate) fn tessellate_entity(
|
||||
|
||||
// ── Section symbol (AcDbSectionSymbol): draw the "A-A" cut mark ──────────
|
||||
//
|
||||
// Model-Documentation section marks arrive as `Unknown` (class 825); the
|
||||
// DWG reader decodes the two cut-line endpoints, the signed end ticks and
|
||||
// the identifier. Synthesize the cut line + end ticks + label glyphs so the
|
||||
// mark is visible on the layout, the way AutoCAD draws it. The raw record is
|
||||
// still preserved for lossless write-back.
|
||||
if let EntityType::Unknown(u) = e {
|
||||
if let Some(s) = u.section_symbol.as_ref() {
|
||||
return section_symbol_wires(
|
||||
document,
|
||||
s,
|
||||
document.section_view_style.as_ref(),
|
||||
h,
|
||||
entity_color,
|
||||
sel,
|
||||
line_weight_px,
|
||||
);
|
||||
}
|
||||
// The DWG reader decodes the two cut-line endpoints, the signed end ticks
|
||||
// and the identifier. Synthesize the end ticks + arrowheads + label glyphs
|
||||
// so the mark is visible on the layout, the way AutoCAD draws it. The raw
|
||||
// record is still preserved for lossless write-back.
|
||||
if let EntityType::SectionSymbol(s) = e {
|
||||
return section_symbol_wires(
|
||||
document,
|
||||
s,
|
||||
document.section_view_style.as_ref(),
|
||||
h,
|
||||
entity_color,
|
||||
sel,
|
||||
line_weight_px,
|
||||
);
|
||||
}
|
||||
// Drawing-view borders are non-plotting aids: nothing is drawn.
|
||||
if let EntityType::ViewBorder(_) = e {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
// ── Dimension baked-block fast path ─────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user