forked from 1b-agent/opencadstudio-upstream
Add ocs_doc_api: object-oriented CAD entity API (v2)
New crate crates/ocs_doc_api: object-centric facade (DocApi -> Document -> collections -> typed handles), transport-agnostic wire layer (DocApiEnvelope = single op | read-only query batch), per-op autocommit (no write transactions), bulk ops with upfront-validation all-or-nothing, structured ApiError, and build-time codegen (spec/entities.toml -> ops/query enums, api_reference.md, binding_schema.json). ocs_plugin_api: append-only PluginRequest::DocApiRequest / PluginResponse:: DocApiResponse (serde_bytes payload) + defaulted HostApi::doc_api_dispatch. Host: DocApiBackend impl for HostSession (src/app/doc_api.rs) mapping to scene primitives (solid_models lift-on-miss, register_prepared_solid_model, meshes metrics), entity conversions (doc_api_convert.rs), HostSession accessors + doc_api_dispatch override. Tests: 592 host lib (incl. 7 DocApi integration tests: create/boolean/query, unknown-id, transform-many all-or-nothing, query-batch cap, 2D/geometric/DWG roundtrips), 8 crate unit tests. Examples + README/ARCHITECTURE/IMPLEMENTATION docs.
This commit is contained in:
1 parent
9129c85f97
commit
e41086b058
44 files changed
+4837
-12
No files matched your search
@@ -0,0 +1,53 @@
|
||||
//! Example 2 — Construct two solids and intersect them (the canonical boolean).
|
||||
//!
|
||||
//! Run: `cargo run --example e2_intersect_two_solids --features host`
|
||||
//!
|
||||
//! Shows: `intersect` / `union` / `subtract` on `Solid`, `erase_sources`
|
||||
//! semantics (the result lives at the first input's id, the second is erased),
|
||||
//! and `OpGroup` cleanup on failure.
|
||||
|
||||
mod common;
|
||||
|
||||
use ocs_doc_api::{DocApi, HasId, OpGroup};
|
||||
|
||||
fn main() -> ocs_doc_api::ApiResult<()> {
|
||||
let api = DocApi::in_process(common::MockBackend::default(), 0);
|
||||
let doc = api.document(api.active_tab());
|
||||
let mut grp = OpGroup::new();
|
||||
|
||||
// Two overlapping boxes: [0,10]^3 and [5,15]^3.
|
||||
let a = grp.track(doc.solids().create_cuboid([0.0, 0.0, 0.0], [10.0; 3]))?;
|
||||
let b = grp.track(doc.solids().create_cuboid([5.0, 5.0, 5.0], [10.0; 3]))?;
|
||||
|
||||
// intersect -> SolidBoolean{Intersection, erase_sources:true}. The result is
|
||||
// returned AT `a`'s id; `b` is erased. [5,10]^3 = volume 125.
|
||||
let lens = match a.intersect(&b) {
|
||||
Ok(l) => {
|
||||
grp.commit(); // keep everything
|
||||
l
|
||||
}
|
||||
Err(e) => {
|
||||
grp.compensate(&doc)?; // best-effort: delete the two boxes
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(lens.id(), a.id(), "result lives at the first input's id");
|
||||
let vol = lens.volume()?;
|
||||
let bb = lens.bounds()?;
|
||||
println!("intersection volume = {vol:.2} (expected 125)");
|
||||
println!("intersection bounds = {bb:?}");
|
||||
|
||||
// union / subtract follow the same shape. Fresh inputs (b was erased above).
|
||||
let c = doc.solids().create_cuboid([0.0, 0.0, 0.0], [10.0; 3])?;
|
||||
let d = doc.solids().create_cuboid([5.0, 5.0, 5.0], [10.0; 3])?;
|
||||
let uni = c.union(&d)?;
|
||||
// union volume = 1000 + 1000 - 125 (overlap) = 1875.
|
||||
println!("union volume = {:.2} (expected 1875)", uni.volume()?);
|
||||
|
||||
let e = doc.solids().create_cuboid([0.0, 0.0, 0.0], [10.0; 3])?;
|
||||
let f = doc.solids().create_cuboid([5.0, 5.0, 5.0], [10.0; 3])?;
|
||||
let diff = e.subtract(&f)?;
|
||||
println!("difference volume = {:.2} (expected 875)", diff.volume()?);
|
||||
Ok(())
|
||||
}
|
||||
Reference in new issue
Block a user