diff --git a/docs/automation/README.md b/docs/automation/README.md index 1476e046..0c1d1e7f 100644 --- a/docs/automation/README.md +++ b/docs/automation/README.md @@ -19,7 +19,9 @@ can act → observe → act. | `{"op":"open","path":"plan.dwg"}` | entity summary | | `{"op":"run","cmd":"LAYER Walls"}` | `{"ok":true,"cmd":...,"entities":N,"added":D}` | | `{"op":"entities"}` | `{"ok":true,"total":N,"by_type":{"Line":42,...}}` | -| `{"op":"query","type":"Line","layer":"Walls"}` | per-entity `{handle,type,layer,…geometry}` (filters + `limit` optional) | +| `{"op":"query","type":"Line","layer":"Walls"}` | per-entity `{handle,type,layer,…geometry}` (Line/Circle/Arc/Point/Ellipse/Text/MText/Polyline/Insert; filters + `limit` optional) | +| `{"op":"layers"}` | layers `{name,color,off,frozen,locked}` + the current layer | +| `{"op":"header"}` | drawing variables (units, PDMODE/PDSIZE, LTSCALE, …) | | `{"op":"select","handles":["2B"]}` | set the selection (by `handles`, `type`, or `layer`; `clear` to deselect) → `{"ok":true,"selected":N}` | | `{"op":"undo"}` / `{"op":"redo"}` | step the document history → entity summary | | `{"op":"save","path":"out.dwg"}` | `{"ok":true,"saved":"out.dwg"}` (path optional once opened/saved) | diff --git a/docs/automation/ocs.py b/docs/automation/ocs.py index a0a59eb7..91ffac30 100644 --- a/docs/automation/ocs.py +++ b/docs/automation/ocs.py @@ -79,6 +79,14 @@ class Ocs: """List entities (handle, type, layer, geometry), optionally filtered.""" return self._send(op="query", type=type, layer=layer, limit=limit) + def layers(self) -> dict[str, Any]: + """List layers (name, color, on/off, frozen, locked) and the current one.""" + return self._send(op="layers") + + def header(self) -> dict[str, Any]: + """Read drawing header variables (units, PDMODE/PDSIZE, LTSCALE, …).""" + return self._send(op="header") + def select( self, handles: Optional[list[str]] = None, diff --git a/src/app/automation.rs b/src/app/automation.rs index b8a6224f..df24fb57 100644 --- a/src/app/automation.rs +++ b/src/app/automation.rs @@ -86,6 +86,31 @@ fn entity_json(e: &acadrust::EntityType) -> Value { E::Point(p) => { map.insert("location".into(), v3(p.location)); } + E::Ellipse(el) => { + map.insert("center".into(), v3(el.center)); + map.insert("major_axis".into(), v3(el.major_axis)); + } + E::Text(t) => { + map.insert("value".into(), json!(t.value)); + map.insert("position".into(), v3(t.insertion_point)); + map.insert("height".into(), json!(t.height)); + } + E::MText(t) => { + map.insert("value".into(), json!(t.value)); + map.insert("position".into(), v3(t.insertion_point)); + map.insert("height".into(), json!(t.height)); + } + E::LwPolyline(pl) => { + let pts: Vec = pl + .vertices + .iter() + .map(|v| json!([v.location.x, v.location.y])) + .collect(); + map.insert("vertices".into(), json!(pts)); + } + E::Insert(ins) => { + map.insert("block".into(), json!(ins.block_name)); + } _ => {} } obj @@ -151,6 +176,50 @@ impl OpenCADStudio { } "entities" => self.entity_summary(), "query" => self.entity_query(&req), + "layers" => { + let i = self.active_tab; + let layers: Vec = self + .tabs[i] + .scene + .document + .layers + .iter() + .map(|l| { + let mut o = json!({ + "name": l.name, + "off": l.is_off(), + "frozen": l.is_frozen(), + "locked": l.is_locked(), + }); + let m = o.as_object_mut().expect("json object"); + if let Some(aci) = l.color.index() { + m.insert("color".into(), json!(aci)); + } + if let Some((r, g, b)) = l.color.rgb() { + m.insert("rgb".into(), json!([r, g, b])); + } + o + }) + .collect(); + json!({ + "ok": true, + "current": self.tabs[i].scene.document.header.current_layer_name, + "layers": layers, + }) + } + "header" => { + let h = &self.tabs[self.active_tab].scene.document.header; + json!({ + "ok": true, + "current_layer": h.current_layer_name, + "current_text_style": h.current_text_style_name, + "insertion_units": h.insertion_units, + "pdmode": h.point_display_mode, + "pdsize": h.point_display_size, + "ltscale": h.linetype_scale, + "annotation_scale_value": h.annotation_scale_value, + }) + } "undo" => { let _ = self.update(super::Message::Undo); self.entity_summary()