- CreateText/CreateMText/SetTextContent ops + GetTextContent query (append-only). - backend add_text/add_mtext/set_text_content/text_content (Text.value/MText.value). - facade create_text/create_mtext + Text/MText handles with content()/set_content(). - Text/MText coarse bounds + transform (insertion point); ensure_transformable. - spec Text/MText families; api_reference + binding_schema regenerated; mocks. - can_modify backend hook (exists + not-locked) for SetTextContent validation. - consistency baseline extended with the appended variants. - Test phase2b_text_mtext_create_content_transform -> 605 host lib + 3 consistency green.
7.0 KiB
ocs_doc_api — Implementation status & roadmap
What ocs_doc_api supports now, and the outstanding first-level entities
and methods to be supported, in phases. "First-level" means the document's
top-level entity store (model/paper-space direct children, not block-nested
content).
✅ Supported (v1)
Solids
| Capability | Method / op | Notes |
|---|---|---|
| Primitives | create_cuboid / create_sphere / create_cylinder / create_cone / create_torus / create_wedge |
CreateSolid(SolidPrimitive) → brep::make::* |
| Sweep | extrude(profile, dir) / revolve(profile, pivot, axis, angle) |
Extrude/Revolve → brep::extrude/brep::revolve; profile = Line/Circle/Arc/LwPolyline |
| Booleans | intersect / union / subtract |
SolidBoolean{op, a, b, erase_sources:true} → brep::combine |
| Transform | transform(placement) (in-place) |
Transform{id, placement} → brep::transform; solids |
| Bounds | bounds() |
GetBounds → brep::body_bounds (lift-on-miss) |
| Volume | volume() |
GetVolume → meshes.metrics cache, mesh-divergence fallback |
| Centroid | centroid() |
GetCentroid → meshes.metrics cache, mesh-divergence fallback |
| Delete | delete() / delete_many |
Delete/DeleteMany |
Minimal 2D (phase-1 set, used as profiles/inputs)
| Capability | Method / op | Notes |
|---|---|---|
| Line | create_line → bounds, transform |
CreateCurve(Line) |
| Circle | create_circle → bounds, transform |
CreateCurve(Circle) |
| Arc | (create via host) → transform, profile | usable as sweep profile |
| Polyline | create_polyline → bounds, transform, add_vertex |
CreateCurve(Polyline); AddVertex inserts a vertex |
| Point | create_point / create_points (bulk) → transform |
CreateCurve(Point) / CreateMany |
| Transform (2D) | transform(placement) / transform_many |
Line/Circle/Arc/Point/LwPolyline via acadrust |
Cross-cutting
| Capability | Method | Notes |
|---|---|---|
| Lookup / downcast | entities().get(id) → Entity; as_solid() |
generic, any family |
| Bulk create | create_points(&[..]), CreateMany |
all-or-nothing, one undo step |
| Bulk transform | transform_many(&ids, placement) |
all-or-nothing, solids + 2D families |
| Bulk delete | delete_many(&ids) |
all-or-nothing; OpGroup::compensate uses it |
| Read batch | query_batch(|q| …) |
read-only, one round-trip, no bump |
| Revision guard | revision() / assert_revision(rev) |
read-modify-write guard |
| Failure cleanup | OpGroup |
best-effort, client-side (NOT a transaction) |
| Binding handover | binding_schema_json() |
merged object-model + wire-layout schema |
| DWG round-trip | — | verified: intersected solids survive write→reload with valid ACIS (test) |
🚧 Roadmap — phase status
Phases are spec-additive: each is a [[family]]/[[family.method]] block in
spec/entities.toml + a codegen bump + facade/backend wiring (see
ARCHITECTURE.md § Workflow). No protocol change; new Operation/Query
variants append at enum end.
Status: Phase 0 (supported-family methods), Phase 2a (full 2D curves), Phase 3 (block references), Phase 4 (viewports), Phase 5 (media read-mostly) are done (all tested; 601 host lib + 8 crate unit tests green). Remaining sub-items: Phase 2b (annotations/hatch/dimension typed ops), attributes + nested traversal (P3), set_view + view query (P4), typed media ops (P5).
Phase 2 — full 2D + annotations
- Done (2a): typed curve families
ArcCurve/Ellipse/Spline/Ray/XLine—create_arc/create_ellipse/create_spline/create_ray/create_xline, bounds (Arc coarse full-circle, Ellipse major-axis radius, Spline control-point bbox; Ray/XLine unbounded →Unsupported), and transform (all five + the phase-1 set) via acadrust. Covered byphase2_*tests. - Done (2b-a): annotations
Text/MText—create_text/create_mtext(CreateText/CreateMTextwire ops),content()/set_content()(newGetTextContentquery +SetTextContentop), transform (insertion point), coarse bounds. Covered byphase2b_*test. - Remaining (2b-b/c):
Hatch(create + boundary query),Dimension(typed sub-types). - Unblocked:
add_vertex(polyline) and sweep profiles (Line/Circle/Arc/LwPolyline) are supported (Phase 0).
Phase 3 — containers
- Done:
create_insert(block_name, point, scale, rotation)→Operation::CreateInsert(validates the BlockRecord exists; unknown block →Validation, no mutation). Inserttransformmoves itsinsert_point. Covered byphase3_*test. - Remaining:
AttributeDefinition/AttributeEntitytyped create + attribute get/set; read-only nested block-content traversal.
Phase 4 — paper-space & viewports
- Done:
create_viewport(center, width, height, view_target, view_height)→Operation::CreateViewport;bounds()= center ± width/2,height/2;transformmoves the paper-space center. Covered byphase4_*test. - Remaining:
set_view(retarget/re-zoom an existing viewport) and a viewport-view query (view target/center/scale DTOs).
Phase 5 — media & misc (read-mostly)
- Done: media/misc families report a real
kindviaGetEntity(RasterImage,Table,Leader,MultiLeader,MLine,Mesh,Helix,Region,Body,Surface,Face3D,Dimension,Hatch) instead of "Other";RasterImagehas coarse bounds (insertion + u·width + v·height); genericdeleteworks on all. Covered byphase5_*test. - Remaining: typed create/property ops for
RasterImage/Table/light; these largely stay read-onlyEntityViewDTOs (typed ops only where the spec declares an action mapping).
🔧 Outstanding methods on supported families
| Method | Family | Status | Blocker |
|---|---|---|---|
loft(sections) |
Solid | not started | multi-profile kernel op + spec |
| Bulge-arc polyline profiles | Solid sweep | partial | entity_to_profile_curves emits straight segments; bulge arcs need arc-segment conversion |
GetCentroid/GetVolume accuracy |
Solid | mesh approx | render-mesh LOD tolerance vs query tolerance |
Completed (Phase 0): extrude, revolve (profiles: Line/Circle/Arc/LwPolyline),
add_vertex (polyline), non-solid transform + transform_many (Line/Circle/Arc/
Point/LwPolyline). Covered by phase0_* tests in src/app/doc_api.rs.
Design invariants to preserve when extending
- Per-op autocommit; no multi-op write transactions.
- Per-op atomicity: validate+compute before
push_undo; failed op = no mutation, no undo, no revision bump. - Bulk ops: single op, all-or-nothing via upfront validation, item-capped.
- New
Operation/Queryvariants append at the end (bincode stability). - Host geometry stays in the host; the wire carries
ObjectId+ plain-data DTOs. binding_schema.jsonandapi_reference.mdregenerate from the spec and are CI drift-checked — updatespec/entities.toml+src/gen/layouts.jsonfor every wire change.