forked from 1b-agent/opencadstudio-upstream
feat(annotative): synthesize per-object contexts + editable UI
Make objects genuinely annotative — carrying real per-scale representations that interoperate with other CAD apps — rather than just a native flag. `create_annotation_context` synthesizes the extension-dict chain (AcDbContextDataManager -> ACDB_ANNOTATIONSCALES -> per-scale leaf) from the entity's placement; the editable Annotative toggle now covers Text and block references as well as MText/MLeader; and a new "Annotation Object Scale" dialog (OBJECTSCALE) adds/removes an object's per-scale memberships. Requires the acadrust ObjectContextData encoder (Cargo.lock bump). Also fixes a render bug where objects carrying an *empty* ACDB_ANNOTATIONSCALES (a single-representation marker with no per-scale reps) were treated as annotative and (mis)scaled by the annotation factor in scaled paper viewports, ballooning the text: an object is now annotative-by-context only when its scale collection is non-empty, so such objects render at their base geometry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
31d3023167
commit
c0844ad55c
14 files changed
+922
-30
No files matched your search
+27
-1
@@ -1943,7 +1943,7 @@ impl Scene {
|
||||
/// Scales are matched by their `name` field, not the dictionary key — some
|
||||
/// files key the entries by an internal identifier (`*A1`, `A0`, …) that
|
||||
/// bears no relation to the scale name.
|
||||
fn scale_object_handle(&self, name: &str) -> Option<Handle> {
|
||||
pub(crate) fn scale_object_handle(&self, name: &str) -> Option<Handle> {
|
||||
use acadrust::objects::ObjectType;
|
||||
self.document.objects.iter().find_map(|(h, o)| match o {
|
||||
ObjectType::Scale(s) if !s.is_temporary && s.name.eq_ignore_ascii_case(name) => {
|
||||
@@ -1953,6 +1953,32 @@ impl Scene {
|
||||
})
|
||||
}
|
||||
|
||||
/// Resolve the current annotation scale (CANNOSCALE) to a real `Scale`
|
||||
/// object handle, materializing the object from the scale list when the
|
||||
/// drawing names the scale but has no `Scale` object for it. Returns `None`
|
||||
/// when there is no current annotation scale. Used when giving an object a
|
||||
/// per-object annotation context (the context's `340` must point at a real
|
||||
/// `AcDbScale`).
|
||||
pub(crate) fn current_annotation_scale_handle(&mut self) -> Option<Handle> {
|
||||
let name = self.document.header.current_annotation_scale.clone();
|
||||
if name.trim().is_empty() {
|
||||
return None;
|
||||
}
|
||||
self.scale_handle_ensuring(&name)
|
||||
}
|
||||
|
||||
/// Resolve a named annotation scale to a real `Scale` object handle,
|
||||
/// materializing the object from the scale list when the drawing names the
|
||||
/// scale (e.g. a virtual fallback scale) but has no `Scale` object for it.
|
||||
pub(crate) fn scale_handle_ensuring(&mut self, name: &str) -> Option<Handle> {
|
||||
if let Some(h) = self.scale_object_handle(name) {
|
||||
return Some(h);
|
||||
}
|
||||
let (paper, drawing) = self.scale_paper_drawing(name).unwrap_or((1.0, 1.0));
|
||||
self.add_scale(name, paper, drawing);
|
||||
self.scale_object_handle(name)
|
||||
}
|
||||
|
||||
/// Add a named annotation scale to the drawing's `ACAD_SCALELIST`. Returns
|
||||
/// `false` if a scale with that name already exists. Creates the SCALELIST
|
||||
/// dictionary (and registers it in the root dictionary) when the drawing
|
||||
|
||||
Reference in new issue
Block a user