feat: integrate SimpleCADAPI 2.0.2 CAD workflows
This commit is contained in:
@@ -50,7 +50,99 @@ top_faces = [face for face in body.get_faces() if "face.top" in scad.list_tags(s
|
||||
print(len(top_faces))
|
||||
```
|
||||
|
||||
Use `apply_tag(shape=..., tag=...)` for user-authored semantic tags and `list_tags(shape=...)` for deterministic inspection. Keep numeric dimensions, measurements, and rich descriptive data in metadata rather than tags.
|
||||
Use `apply_tag(shape=..., tag=...)` for a local user-authored tag. Use `apply_tag_rselection(...)` when a selector, explicit downward inheritance, or an independent semantic shape view is required. Inspect `local`, `inherited`, `effective`, or `lineage` with `list_tags(shape=..., scope=...)` and `explain_tag(...)`. `effective` excludes lineage. Keep numeric dimensions, measurements, operation events, source roles, and rich descriptive data in typed metadata rather than tags.
|
||||
|
||||
## Feature Output Role Surface
|
||||
|
||||
The following roles are operation-owned, kernel-proven sets. `one` means exactly
|
||||
one result is required when the role is requested; `many` means at least one
|
||||
result is required and all proven results are tagged.
|
||||
|
||||
| Operation | Role | Kind | Cardinality | Named tag argument |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Box | `box.bottom` | Face | one | `bottom_face_tag` |
|
||||
| Box | `box.top` | Face | one | `top_face_tag` |
|
||||
| Box | `box.front` | Face | one | `front_face_tag` |
|
||||
| Box | `box.back` | Face | one | `back_face_tag` |
|
||||
| Box | `box.left` | Face | one | `left_face_tag` |
|
||||
| Box | `box.right` | Face | one | `right_face_tag` |
|
||||
| Cone | `cone.start` | Face | one | `start_face_tag` |
|
||||
| Cone | `cone.end` | Face | one | `end_face_tag` |
|
||||
| Cone | `cone.side` | Face | one | `side_face_tag` |
|
||||
| Cone | `cone.start_boundary` | Edge | one | `start_edge_tag` |
|
||||
| Cone | `cone.end_boundary` | Edge | one | `end_edge_tag` |
|
||||
| Cone | `cone.seam` | Edge | one | `seam_edge_tag` |
|
||||
| Extrude | `extrusion.start` | Face | one | `start_face_tag` |
|
||||
| Extrude | `extrusion.end` | Face | one | `end_face_tag` |
|
||||
| Extrude | `extrusion.side` | Face | many | `side_faces_tag` |
|
||||
| Revolve | `revolution.start` | Face | one | `start_face_tag` |
|
||||
| Revolve | `revolution.end` | Face | one | `end_face_tag` |
|
||||
| Revolve | `revolution.side` | Face | many | `side_faces_tag` |
|
||||
| Fillet | `fillet.patch` | Face | many | `generated_faces_tag` |
|
||||
| Chamfer | `chamfer.patch` | Face | many | `generated_faces_tag` |
|
||||
| Shell | `shell.body_face` | Face | many | `body_faces_tag` |
|
||||
| Shell | `shell.offset_face` | Face | many | `offset_faces_tag` |
|
||||
| Shell | `shell.closing_descendant` | Face | many | `closing_faces_tag` |
|
||||
| Shell | `shell.wall` | Edge | many | `wall_edges_tag` |
|
||||
| Loft | `loft.start` | Face | one | `start_face_tag` |
|
||||
| Loft | `loft.end` | Face | one | `end_face_tag` |
|
||||
| Loft | `loft.side` | Face | many | `side_faces_tag` |
|
||||
| Sweep | `sweep.start` | Face | one | `start_face_tag` |
|
||||
| Sweep | `sweep.end` | Face | one | `end_face_tag` |
|
||||
| Sweep | `sweep.side` | Face | many | `side_faces_tag` |
|
||||
| Twisted sweep | `twisted_sweep.start` | Face | one | `start_face_tag` |
|
||||
| Twisted sweep | `twisted_sweep.end` | Face | one | `end_face_tag` |
|
||||
| Twisted sweep | `twisted_sweep.side` | Face | many | `side_faces_tag` |
|
||||
|
||||
Every feature also accepts `result_tag` for its one result Solid. Each output
|
||||
role has one semantic tag argument named for the target, such as
|
||||
`start_face_tag`, `side_faces_tag`, or `generated_faces_tag`; there is no generic
|
||||
role-to-tag mapping. Malformed tags, unavailable roles, and cardinality
|
||||
mismatches fail the operation. A full revolve has no
|
||||
separate start/end cap roles. Shell roles vary with actual OCC history and are
|
||||
not synthesized when unavailable. Box Edge roles are unsupported because the
|
||||
kernel builder has no equivalent direct Edge witnesses. Sweep and twisted sweep
|
||||
reject profiles with inner wires. A pointed cone has no `cone.end` cap Face, but its
|
||||
`cone.end_boundary` remains the kernel-proven degenerate apex Edge.
|
||||
|
||||
Use `ql.output_role(role_name=...)` to query operation role evidence. Use
|
||||
`ql.source_binding(binding_id=...)` and `ql.source_topology(topo_id=...)` only for
|
||||
projected local `TagBinding` evidence.
|
||||
|
||||
## Unified Tag Contract
|
||||
|
||||
Topology identity and user semantics use the same `TagBinding` and public query
|
||||
surfaces. The authoring path and evidence determine projection behavior, not the
|
||||
tag text:
|
||||
|
||||
- `tag_prefix="housing"` creates topology-identity tags such as
|
||||
`housing.face.top` and `housing.solid`. These bindings carry `topology_name`
|
||||
evidence and identify kernel-proven result topology.
|
||||
- `top_face_tag="role.cover"` attaches `role.cover` to the kernel-proven top
|
||||
Face. Its binding carries operation output role evidence.
|
||||
- `result_tag="part.housing"` attaches `part.housing` to the returned Solid.
|
||||
Its binding carries operation result evidence.
|
||||
|
||||
All three are discoverable with `list_tags(...)` and `explain_tag(...)` and
|
||||
queryable with `ql.tag(...)`. A topology object may carry all three. Only a
|
||||
topology-identity binding projects through the stricter exact-correspondence
|
||||
path; a tag string does not opt into that behavior by resembling a topology tag.
|
||||
|
||||
## Constrained Sketch Tag Surface
|
||||
|
||||
Sketch entity IDs are creation-time local identifiers. When a constrained
|
||||
profile is promoted, the exact ordered promotion map creates topology-identity
|
||||
`TagBinding`s with `topology_name` evidence:
|
||||
|
||||
- Profile `bottom` in sketch `rect`: `sketch.rect.profile.bottom` on the Face or Wire.
|
||||
- Entity `right` in sketch `rect`: `sketch.rect.entity.right` on its promoted Edge.
|
||||
|
||||
The promotion path validates that the generated Edge count equals the entity
|
||||
map before attaching tags. It does not use geometric similarity, area,
|
||||
normal, position, or enumeration order to repair a mismatch. Compatibility
|
||||
tags such as `sketch_entity.right` remain ordinary compatibility tags.
|
||||
Downstream features project topology-identity bindings only when kernel history
|
||||
proves exact source-to-target correspondence.
|
||||
|
||||
## Recommended reading order
|
||||
|
||||
@@ -64,12 +156,16 @@ Use `apply_tag(shape=..., tag=...)` for user-authored semantic tags and `list_ta
|
||||
## Typical replayable surface
|
||||
|
||||
```python
|
||||
from simplecadapi import GraphSession, export_model_json, replay_model_json
|
||||
import simplecadapi as scad
|
||||
|
||||
with GraphSession() as session:
|
||||
...
|
||||
@scad.model(graph_id="demo")
|
||||
def build_model():
|
||||
result = ...
|
||||
scad.capture_result(value=result)
|
||||
return result
|
||||
|
||||
model_json = export_model_json(session=session)
|
||||
rebuilt = replay_model_json(json_str=model_json)
|
||||
model = build_model()
|
||||
model_json = model.model_json
|
||||
rebuilt = model.replay()
|
||||
print(len(rebuilt))
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user