forked from 1b-agent/opencadstudio-upstream
feat(automation): entity, block, publishing and REST operations from the fork
The operations docs/automation/API-SPEC.md (PR #1383) describes, brought over from huaninstratech/OpenCADStudio so the specification no longer runs ahead of the code: - entity CRUD: entities_create, entities_delete, entities_transform, entities_copy_to, and `where` filters on query - blocks and export: block_define, block_delete, a normalised wblock - publishing: layout_create, page_setup_set, plot (per_page included) - metadata: sysvar, xdata_set / xdata_get, file_identity - collections: group_create, selection_set_save / load - control plane: batch, events, view_focus, close - the REST transport: `--http <port>`, the /api/v1 routes and their OpenAPI 3 description - person-in-the-loop picks: user_select and getpoint, hosted by the GUI over the same REST routes, with on-screen pending signals Taken from the fork's commits b7a7ed80, 69396b42, 64f1cf6a, c3aafc8e, bb5a7bfa, 52317a5c, 50d293ba, b90e194f, 517c6397, 53a5c4c9, a49ac045, 37de5a46, a78b1822, 6d9aed2a, 33f522da, 5b5cafe2, 02a7e78d, 94df40dc, fd5bc14d, 485fac61 and 2c5fc994. Left out on purpose: 37de5a46 also removed the donation surface (the Patreon fetch, the donation prompt, the Start-page supporters rail, the DONATE command and its locale strings) and replaced the About dialog's call to action; that is the fork's own product decision and stays out. The fork's version bump and its unrelated IFC/BIM work are not part of this. Adapted while porting: the REST server and the GUI bridge are desktop-only and a template start is refused in the web build, so the wasm target still compiles; the two plot tests read the PDF through the shared stream helper, because exported streams are Flate-compressed; the benches set the new crosshair field; comments and docs describe each operation in its own terms rather than by another product's API names. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
531ba44faa
commit
279a87418e
37 files changed
+8795
-82
No files matched your search
@@ -24,6 +24,18 @@ pub fn tool() -> ToolDef {
|
||||
///
|
||||
/// Returns `Err` if the block is not found or has no entities.
|
||||
pub fn extract_block_to_doc(src: &CadDocument, block_name: &str) -> Result<CadDocument, String> {
|
||||
let mut out = CadDocument::new();
|
||||
extract_block_into(src, block_name, &mut out)?;
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Extract the block's entities into `out` (a fresh document or a loaded
|
||||
/// template whose tables/styles should survive — Catalog §2.1).
|
||||
pub fn extract_block_into(
|
||||
src: &CadDocument,
|
||||
block_name: &str,
|
||||
out: &mut CadDocument,
|
||||
) -> Result<(), String> {
|
||||
let br = src
|
||||
.block_records
|
||||
.get(block_name)
|
||||
@@ -38,7 +50,6 @@ pub fn extract_block_to_doc(src: &CadDocument, block_name: &str) -> Result<CadDo
|
||||
.into_owned());
|
||||
}
|
||||
|
||||
let mut out = CadDocument::new();
|
||||
// Copy layers referenced by the block entities.
|
||||
for h in &handles {
|
||||
if let Some(e) = src.get_entity(*h) {
|
||||
@@ -71,7 +82,7 @@ pub fn extract_block_to_doc(src: &CadDocument, block_name: &str) -> Result<CadDo
|
||||
.into_owned());
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build a standalone `CadDocument` from an explicit list of entity handles
|
||||
@@ -80,12 +91,21 @@ pub fn extract_entities_to_doc(
|
||||
src: &CadDocument,
|
||||
handles: &[acadrust::Handle],
|
||||
) -> Result<CadDocument, String> {
|
||||
let mut out = CadDocument::new();
|
||||
extract_entities_into(src, handles, &mut out)?;
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Extract the listed entities into `out` (fresh document or template base).
|
||||
pub fn extract_entities_into(
|
||||
src: &CadDocument,
|
||||
handles: &[acadrust::Handle],
|
||||
out: &mut CadDocument,
|
||||
) -> Result<(), String> {
|
||||
if handles.is_empty() {
|
||||
return Err(t!("No entities selected for WBLOCK.").into_owned());
|
||||
}
|
||||
|
||||
let mut out = CadDocument::new();
|
||||
|
||||
for &h in handles {
|
||||
if let Some(entity) = src.get_entity(h) {
|
||||
if matches!(entity, EntityType::Block(_) | EntityType::BlockEnd(_)) {
|
||||
@@ -109,5 +129,31 @@ pub fn extract_entities_to_doc(
|
||||
return Err(t!("None of the selected entities could be exported.").into_owned());
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Translate every entity of `out` so the overall bounds minimum lands on
|
||||
/// the origin — SPM.ACAD's clone flow normalizes the new drawing to 0,0,0
|
||||
/// after the copy (Catalog §2.1/CF-01.2). Opt-in per request; the
|
||||
/// interactive WBLOCK export keeps the source coordinates.
|
||||
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
|
||||
pub fn normalize_to_origin(out: &mut CadDocument) {
|
||||
let mut min = [f64::INFINITY; 3];
|
||||
for entity in out.entities() {
|
||||
let (lo, _) = crate::scene::convert::tess::entity_bounds(entity);
|
||||
for axis in 0..3 {
|
||||
if lo[axis] < min[axis] {
|
||||
min[axis] = lo[axis];
|
||||
}
|
||||
}
|
||||
}
|
||||
if min.iter().any(|v| !v.is_finite()) {
|
||||
return;
|
||||
}
|
||||
let shift = crate::command::EntityTransform::Affine(acadrust::types::Transform::from_translation(
|
||||
acadrust::types::Vector3::new(-min[0], -min[1], -min[2]),
|
||||
));
|
||||
for entity in out.entities_mut() {
|
||||
crate::scene::view::dispatch::apply_transform(entity, &shift);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user