diff --git a/deps/OCCT/OCCT.cmake b/deps/OCCT/OCCT.cmake index 45263d6ae3..e1a65beef7 100644 --- a/deps/OCCT/OCCT.cmake +++ b/deps/OCCT/OCCT.cmake @@ -24,7 +24,7 @@ endif() # On macOS/Linux OCCT links statically, so an unreferenced toolkit costs build time and no # shipped bytes. The Windows figure is a real DLL cost and has NOT been measured -- an # earlier "3.77 MiB, Windows only" note here covered only two of the three toolkits and is -# not a number to quote. See docs/cad_dependency_weight.md. +# not a number to quote. See docs/HLSD/design-tab.md. if (IN_GIT_REPO) set(OCCT_DIRECTORY_FLAG --directory ${BINARY_DIR_REL}/dep_OCCT-prefix/src/dep_OCCT) diff --git a/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md b/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md deleted file mode 100644 index bf603cf2c1..0000000000 --- a/docs/CAD/GAP_ANALYSIS_vs_ONSHAPE.md +++ /dev/null @@ -1,160 +0,0 @@ -# Orca-CAD vs Onshape — capability gap analysis - -Generated 2026-07-22 by enumerating the source, not from recollection: -`CadFeatureType` and `add_*` in `src/libslic3r/CAD/CadDocument.hpp`, `Tool` in -`src/slic3r/GUI/CAD/DesignPanel.hpp`, `Mode` in `src/slic3r/GUI/CAD/DesignSketchTool.hpp`, -`SketchConstraintType` + `SketchEntity::Type` in `src/libslic3r/CAD/SketchEngine.hpp`, -and the JSON-RPC dispatch in `src/slic3r/GUI/CAD/McpControl.cpp`. - -**Scope note.** Onshape is a cloud PLM platform; Orca is a Design tab inside a -slicer. A large share of Onshape's surface (release management, branching, real-time -collaboration, FEA, rendering, PDM) is out of scope by construction and is listed -separately at the bottom rather than counted as a "missing tool". - ---- - -## 1. What Orca already has - -### 2D sketcher — near parity with Onshape -This is the strongest area. Very little is missing. - -| Category | Orca | -|---|---| -| Entities | Line, Polyline, Arc (3-point / tangent / center), Circle (center / 2-point / 3-point), Point, Ellipse, Elliptical arc, B-spline | -| Shapes | Rectangle (corner / center / oblique / rounded), Slot, Arc-slot, Polygon | -| Edit ops | Fillet, Chamfer, Offset, Mirror, Trim, Extend | -| Transforms | Move, Rotate, Scale, Linear array, Polar array | -| Constraints (19) | Fix, Coincident, Horizontal, Vertical, Distance, LockX, LockY, EqualLength, Parallel, Perpendicular, Concentric, Tangent, Midpoint, Symmetric, Angle, Radius, Diameter, PointOnLine, PointOnObject | -| Dimensions | Length, Diameter, Radius, Angle, Distance, Distance-to-line | - -Solver: vendored SolveSpace (`libslvs`, GPL-3.0) — the same solver lineage as a -commercial-grade sketcher. - -### Part features - -| Present | Notes | -|---|---| -| Extrude | + up-to-face / up-to-point, taper, flip | -| Revolve | angle-arc gizmo | -| Sweep | along a path | -| Loft | multi-profile | -| Fillet / Chamfer | edge-level | -| Draft | face taper | -| Shell | wall thickness + open face | -| Hole / Thread | face-aware placement | -| Pattern | linear + circular | -| Boolean | New / Add / Cut / Intersect, with face-mating | -| Cut | plane-based, signed offset | -| Datum plane | offset / 2-face / 2-edge derived | -| Import | STEP (B-rep) + mesh→B-rep (native mesh2step port) | -| Export | STEP (native B-rep, not tessellated) | -| Multi-body | + per-body colour | -| Section view | with flip | -| Undo/redo | full feature-tree recompute | -| 3MF persistence | parametric recipe survives save/load | - -### Automation -9 MCP JSON-RPC methods: `describe_tools`, `describe_scene`, `query_topology`, -`measure`, `slice_body`, `import_step`, `import_mesh`, `validate_against`, plus -build actions `extrude`, `revolve`, `fillet`, `chamfer`, `hole`, `boolean`, `pattern`. -Onshape's equivalent is its REST API + FeatureScript. - ---- - -## 2. Missing tools — ranked by impact - -### Tier 1 — structural absences (whole subsystems) - -**1. Assemblies and mates.** Entirely absent. No assembly document, no mate -connectors, no fastened / revolute / slider / cylindrical / planar / ball / pin-slot -mates, no assembly patterns, no interference detection, no exploded views. -`bool_target_face` / `bool_tool_face` do face-to-face *mating* for a boolean, which -is geometric alignment, not a kinematic joint. -*Impact:* multi-part products cannot be positioned or validated as a mechanism. -*Note:* an MCP-side `align_instance_to_face` / `create_*_mate` vocabulary already -exists on the Onshape bridge in this workspace, so the target semantics are known. - -**2. Drawings / 2D documentation.** Absent. No drawing sheets, dimensioned views, -section/detail views, GD&T, title blocks, or BOM. -*Impact:* nothing manufacturable-by-a-third-party leaves the tool. For 3D printing -this matters less than for machining, which is the honest reason it is Tier 1 by -CAD convention but arguably Tier 3 for this product. - -**3. Variables, equations, configurations.** Absent — no `add_variable`, no -expression evaluation, no configuration table. Every dimension is a literal double. -*Impact:* this is the biggest *parametric* gap. "Make this bracket for an M4 vs M5 -bolt" requires re-editing every dependent feature by hand. Onshape's Variable -Studio + configurations are a core differentiator, and this is the cheapest Tier 1 -item to close for the size of the payoff. - -**4. Surface modelling.** Absent. No surface extrude/revolve/loft/sweep, no fill, -knit, trim/extend surface, offset surface, or thicken. Orca is solid-only. -*Impact:* organic/complex shapes and repair of imported junk geometry are impossible. -OCCT already provides all of it (`TKOffset`, `TKBRep`), so the kernel is not the -blocker — only UI and feature plumbing. - -**5. Sheet metal.** Absent. No flange, bend, tab, relief, or flat-pattern unfold. -*Impact:* arguably out of scope for an FDM slicer; listed for completeness. - -### Tier 2 — individual features with clear demand - -| Missing | Why it matters | Cheap? | -|---|---|---| -| **Mirror body** (part-level) | Sketch mirror exists; mirroring a *solid* about a plane does not. Extremely common. | Yes — OCCT `gp_Trsf` mirror + fuse | -| **Helix / spiral curve** | No helix ⇒ no springs, no custom threads, no spiral vase geometry. Sweep exists but has no helical path to sweep along. | Yes | -| **Move / rotate body as a real feature** | `m_body_xform` exists but is **display-only** (memory #1655) — it never enters the B-rep. Export/boolean see the original position. | Medium | -| **Split body** | Cut removes material; splitting one body into two independently-usable bodies is absent. Very relevant for print-in-parts. | Medium | -| **Thicken** | Solid from a surface/face offset. | Needs surfaces | -| **Rib** | Standard structural feature. | Medium | -| **Delete face / move face / replace face** | Direct/dumb-solid editing — the main tool for fixing imported STEP. Given Orca imports STEP *and* meshes, its absence is felt. | Medium | -| **Datum axis, coordinate system** | Only datum *planes* exist. Axes are needed for revolve/pattern references. | Yes | -| **Mass properties** | `GeometryEngine` computes a volume internally, but there is no volume/mass/COM/inertia readout. For print cost/time estimation this is nearly free to expose. | Yes — trivial | -| **Measure tool in the GUI** | `measure` exists over MCP but there is no interactive measure in the UI. | Yes | -| **Hole standards library** | Hole exists, but no counterbore/countersink/tapped standards (ISO/ANSI) with callouts. | Medium | -| **Project / convert edges into a sketch** | Cannot reference existing solid edges as sketch geometry ("Use" in SolidWorks). A significant sketcher gap given everything else is present. | Medium | -| **Construction geometry** | Could not confirm a construction/reference-line flag on sketch entities. | Yes if absent | -| **Curve tools** | Projected curve, bridging curve, composite curve, 3D fit spline. | Medium | -| **Pattern on curve / pattern faces** | Pattern is linear + circular of whole bodies only; no curve-driven pattern, no feature/face pattern. | Medium | -| **Wrap / emboss** | Text or sketch wrapped onto a curved face. | Hard | -| **Enclose** | Solid from bounded void regions. | Medium | - -### Tier 3 — platform capabilities (out of scope by construction) - -Version control with branching/merging, release management, real-time multi-user -collaboration, cloud PDM, FeatureScript custom-feature authoring, simulation/FEA, -photorealistic rendering, app store/integrations. These are Onshape-the-platform, -not Onshape-the-modeller. Not defects in Orca. - ---- - -## 3. Recommended priority - -If the goal is "credible parametric CAD inside a slicer", the ordering that buys -the most capability per unit of work: - -1. **Variables + expressions** — unlocks genuine parametric reuse; no new kernel work. -2. **Mass properties + GUI measure** — nearly free, immediately useful for printing. -3. **Mirror body, datum axis, helix** — small, self-contained, high-frequency features. -4. **Promote move/rotate body from display-only to a real B-rep feature** — closes a - correctness gap, not just a missing tool (exports currently disagree with the view). -5. **Split body** — high value for print-in-parts workflows. -6. **Project edges into sketch** — the sketcher's most conspicuous hole. -7. **Surface modelling** — large, but OCCT already ships the algorithms. -8. **Assemblies** — largest effort; only worth it if Orca targets multi-part products. - -Deliberately last: drawings and sheet metal — high cost, low relevance to an -FDM-oriented tool. - ---- - -## 4. Honest summary - -Orca's **sketcher is at or near Onshape parity**, and its **solid feature set -covers the mainstream modelling path** (sketch → extrude/revolve/sweep/loft → -dress-up → boolean/pattern). What is absent is *breadth*: assemblies, surfaces, -sheet metal, drawings, and — most importantly for a tool calling itself parametric — -**variables and configurations**. - -The single most defensible criticism is #3: without variables, the feature tree is -parametric in *structure* but not in *value*, so the promise of "change one number -and the model updates" is only half delivered. diff --git a/docs/CAD/cad_dependency_weight.md b/docs/CAD/cad_dependency_weight.md deleted file mode 100644 index 0b64ac8097..0000000000 --- a/docs/CAD/cad_dependency_weight.md +++ /dev/null @@ -1,136 +0,0 @@ -# Dependency weight of the Design/CAD subsystem - -What the Design tab actually costs a maintainer who merges it. Written to be checkable: -every number below is reproducible with the command that produced it, and the places where -a number is still missing say so instead of guessing. - -Measured on Linux x86_64, OCCT V7_6_0, in the `snapmaker-deps` build image. - -## Summary - -| | Cost | -|---|---| -| New third-party dependencies | **none** | -| OCCT build flag | `BUILD_MODULE_ModelingAlgorithms=ON` | -| Extra OCCT toolkits *built* | 3 (TKFillet, TKOffset, TKFeat) | -| Extra OCCT toolkits *linked* | 2 (TKFillet, TKOffset) | -| Vendored code | `src/libslic3r/slvs`, 9,339 lines, 380 KiB, GPLv3 | -| Own object code | 6.79 MiB unstripped `.o` (7.13 MiB with the solver) | - -OCCT is **already** an upstream dependency — Orca uses it for STEP import. The Design tab -does not add a library; it turns on one more OCCT module. - -## The OCCT module flag - -`deps/OCCT/OCCT.cmake` gates the module on `SLIC3R_CAD`: - -```cmake --DBUILD_MODULE_ModelingAlgorithms=${SLIC3R_CAD} # was hard-coded OFF -``` - -With `SLIC3R_CAD=OFF` the deps prefix matches upstream exactly. - -`ModelingAlgorithms` contains 12 toolkits, but **most were already being built**, because -`DataExchange` — the STEP path upstream already ships — depends on them. The honest delta is -only the toolkits that DataExchange's dependency closure does *not* reach: - -``` -ModelingAlgorithms = TKGeomAlgo TKTopAlgo TKPrim TKBO TKBool TKHLR - TKFillet TKOffset TKFeat TKMesh TKXMesh TKShHealing - -already required by DataExchange: TKBO TKBool TKGeomAlgo TKHLR TKMesh - TKPrim TKShHealing TKTopAlgo -true delta: TKFeat TKFillet TKOffset TKXMesh -``` - -Reproduce by walking `adm/MODULES` and each toolkit's `src//EXTERNLIB` in the OCCT -source tree. - -### Sizes of the delta toolkits - -Static archives in the deps prefix. These are *build artifacts*, not shipped bytes — a -static link pulls in only the objects it references: - -| Toolkit | Archive | Referenced by the Design tab? | -|---|---|---| -| TKFillet | 7.40 MiB | yes — `BRepFilletAPI` | -| TKOffset | 5.38 MiB | yes — `BRepOffsetAPI`, `BRepOffset_` | -| TKFeat | 4.42 MiB | **no** | -| TKXMesh | — | not produced at all | - -TKFeat is worth calling out: nothing in the Design tab references it, and it is absent from -the `TKFillet`/`TKOffset` dependency closure, so it is built for nothing. OCCT's module flag -is all-or-nothing per module, which is why it comes along. It costs build time and zero -shipped bytes on any platform that links OCCT statically. - -**A correction to the record.** The comment in `deps/OCCT/OCCT.cmake` and the earlier -summary both said the delta was "TKFillet + TKOffset — 3.77 MiB, Windows only". The toolkit -list was incomplete: TKFeat is built too. The 3.77 MiB figure covers 2 of the 3 built -toolkits and has not been re-derived here — see the gap below. - -## What is not measured yet - -Two numbers a maintainer may reasonably ask for are **not** in this document, because -producing them honestly needs a build this machine cannot do: - -1. **Windows DLL delta.** OCCT builds shared on Windows, so the shipped cost there is real - DLL bytes rather than linker-selected objects. That needs a Windows build to size — - tracked as the cross-platform build proof (`gix`). -2. **Clean-build time delta.** Measuring it means building the deps prefix twice, with the - flag ON and OFF, on the same machine. The incremental figures from day-to-day work do not - answer the question and are not offered as if they did. - -Do not quote a number for either until it has been measured. - -## Vendored solver - -`src/libslic3r/slvs` — the 2D sketch constraint solver extracted from SolveSpace. - -- 19 files: 8 `.cpp`, 11 `.h`, plus `LICENSE` -- 9,339 lines, 380 KiB of source, 0.34 MiB of object code -- **GPLv3**, `LICENSE` preserved verbatim in the vendored directory - -The fork is **AGPLv3**. GPLv3 code combines into an AGPLv3 work without difficulty: AGPLv3 -§13 provides explicit compatibility in that direction. No licence question to resolve. - -It is live code, not a carried corpse — `SketchSolver.cpp` is its only consumer and drives -every sketch constraint in the Design tab. - -## Own code - -Object sizes from the release build (unstripped, so these include debug information and -overstate the shipped contribution): - -| Object | Size | -|---|---| -| DesignPanel.o | 2.22 MiB | -| McpControl.o | 1.69 MiB | -| DesignSketchTool.o | 0.88 MiB | -| CadDocument.o | 0.76 MiB | -| SketchEngine.o | 0.40 MiB | -| DesignCanvas.o | 0.37 MiB | -| GeometryEngine.o | 0.32 MiB | -| SketchSolver.o | 0.15 MiB | -| slvs (all objects) | 0.34 MiB | -| **total** | **7.13 MiB** | - -For scale, the linked binary is 137.1 MiB. - -## Reproducing - -```bash -# toolkit membership and dependency closure -R= -cat $R/adm/MODULES # module -> toolkits -cat $R/src//EXTERNLIB # toolkit -> its dependencies - -# archive sizes -ls -l /lib/libTK{Fillet,Offset,Feat}.a - -# what the Design tab actually references -grep -rE 'BRepFilletAPI|BRepOffsetAPI|BRepOffset_|BRepFeat' src/libslic3r/ - -# vendored solver -wc -l src/libslic3r/slvs/*.cpp src/libslic3r/slvs/**/*.h -head -3 src/libslic3r/slvs/LICENSE -``` diff --git a/docs/CAD/cad_ux_guidelines.md b/docs/CAD/cad_ux_guidelines.md deleted file mode 100644 index d0290a1d3d..0000000000 --- a/docs/CAD/cad_ux_guidelines.md +++ /dev/null @@ -1,704 +0,0 @@ -# Orca-CAD — UX guidelines and design charter - -Status: proposed, v1. Owner: design working group. Applies to the Design tab — -the parametric CAD environment inside OrcaSlicer. - -This document is a **review instrument**, not an essay. Sections 3–9 are written -so that a reviewer can hold a pull request against them and get a yes or a no. -If a rule here cannot be failed, it is badly written and should be rewritten. - ---- - -## 1. Why this exists - -A CAD tool acquires its interface by accretion. Every feature arrives needing -"just one more field", the side panel is the cheapest place to put it, and after -forty features the product is FreeCAD: complete, respected, and abandoned by -almost everyone who opens it once. That end state is not a failure of any single -decision. It is the sum of forty locally reasonable ones taken without a written -rule to violate. - -So we write the rule down first, and we make additions argue against it. - -## 2. Product thesis - -**Orca-CAD is a modelling space for people who want a part, inside the tool that -prints it.** - -Three audiences, one interface: - -- **The fourteen-year-old on a school laptop.** Free software, on the machine - they already have, with no account, no subscription, no licence and no - tutorial. They open the tab because they want a bracket for a bike light, and - an hour later it is printing. This is not the charity case at the bottom of - the list — it is the reason the project is worth doing. A CAD tool that only - the equipped can run is a tool for people who were already going to design - something; this one has to be a creative instrument in the hands of someone - who did not yet know they could make things. Everything in §6.1 exists to - keep that door open, and nothing gets to close it for the convenience of the - other two audiences. -- **The maker** who has an idea and a printer, and who has bounced off FreeCAD. - They should be modelling something real within ten minutes of first opening - the tab, without a tutorial, without knowing the word "constraint". -- **The mechanical designer** who needs assemblies, mates, exploded views, - variables, and a feature history they can edit six months later. They should - not have to leave for SolidWorks the moment the work gets serious. - -The order matters. When a decision helps one audience and hurts another, the -earlier one wins unless there is a written argument for why not. - -The reference for *how it feels* is Shapr3D: direct, gestural, quiet, almost no -chrome, depth revealed by what you touch rather than by what is on screen. The -anti-references are Blender (a modal keyboard language you must learn before the -first success) and FreeCAD (a workbench-and-dialog architecture where the -geometry is a preview of a form you fill in elsewhere). - -We are not cloning Shapr3D's feature set. We are adopting its *interaction -economy*: the smallest number of visible controls that still makes an expert -fast. - -**And one thing neither reference has:** Orca-CAD lives inside a slicer. The -plate, the nozzle, the material and the print constraints are known to the -application at design time. Designing for print is not a plugin here, it is the -home advantage. Where a rule below trades generality for print-awareness, it -trades in favour of print-awareness. - -## 3. The laws - -Non-negotiable. A change that breaks one of these does not get merged on the -grounds that it was easier, that the alternative is more work, or that another -CAD does it that way. Each law carries a test — the question a reviewer asks. - -### L1 — Geometry first: you point, then you act - -Controls live **on the geometry**: handles, arrows, points, small circles and -boxes, with an inline label tab for typed values. Not in a side panel of combos -and spin fields. - -The canonical gesture: **select a face or plane in the viewport, then click the -sketch tool.** Never: click the sketch tool, then choose a plane from a list. -The tool consumes what you pointed at — and, better still, the thing you pointed -at offers the tool itself (§4). - -> **Test.** Can the operation be performed start to finish without the pointer -> leaving the viewport, except to press the tool itself? If a control had to be -> added to a panel to make it work, the design is not finished. - -This is the law the others serve. It was stated after two proposals in a row -reached for a dropdown, and the failure mode it names is real and recurrent: a -fix that "adds a row to the plane combo" is the side-panel pattern wearing a -different hat. - -### L2 — Everything draggable is typable, and everything typable is draggable - -Any value produced by direct manipulation (a fillet radius, an extrude depth, a -pattern spacing, a plane offset) shows a live label on the geometry, and that -label is an editable field. Any value entered numerically has a corresponding -handle in the viewport. - -Dragging is for finding the answer. Typing is for committing to it. A tool that -offers only one of the two is half a tool. - -> **Test.** Point at the number the tool produces. Can you drag it? Can you -> click it and type? Both must be yes. - -### L3 — Noun then verb, always the same way round - -Selection precedes action, without exception, across sketch tools, features, -dress-up, booleans and mates. There is no tool in the product that is armed -first and asks for its input afterwards. - -> **Test.** Does this tool work if the user has already selected the thing they -> want it applied to? Does it work *only* that way? - -### L4 — No modal dialog in the modelling loop - -Dialogs belong to document-level actions: open, save, import, export, preferences. -Modelling never opens one. A feature that needs three values gets three labels on -the geometry, not a form; a feature that needs confirming gets a ghost preview and -a confirm/cancel puck in the scene beside it (§4.2) — an object, not a window: the -camera still orbits, the values are still editable, nothing is blocked. - -> **Test.** Between starting an operation and seeing its result, does a window -> appear that must be dismissed? If yes, redesign. - -### L5 — One click, one visible change - -Every click either changes what is on screen or tells the user why it did not. -A click that opens something invisible, arms an invisible state, or requires a -second identical click to have any effect is a defect, not a design. - -This law exists because we shipped its violation twice. Sketch-tool family -buttons were flyouts whose first click only rendered a pressed state — three -separate sessions filed bugs against tools that were working. Solid picking used -a click *cycle* (first click selects the body, second refines to the face), so -sketching on a face appeared broken to anyone who clicked a face once, the way -every human does. - -> **Test.** Perform the gesture exactly once, as a first-time user would. Take a -> screenshot. Is the state visibly different, and is the difference the one the -> user intended? - -### L6 — The default is the answer four times out of five - -Every option that has a default must have the *common* answer as its default, -measured against real parts, not against generality. "New body" as the default -result of an extrude is wrong: most extrudes join. Radius as the input for a -circle is wrong: drawings give diameter. - -> **Test.** Take ten real parts. In how many is the default correct? Below eight, -> change the default or infer it from context. - -### L7 — Errors are caught before the commit, in the user's words - -A self-intersecting profile, a cut that removes no material, a wall thinner than -the nozzle: these are reported at the moment they become knowable, on the -geometry that is wrong, phrased as what happened and what to do — not as a kernel -exception after the fact, and never silently. - -> **Test.** Is the failure detectable before the user commits? Then it must be -> reported before the user commits. Read the message aloud: does it name a thing -> the user can see and an action they can take? - -### L8 — The camera is the application's job - -Selecting a sketch plane orients the view to it. Committing a feature does not -throw the camera away. Zoom-to-fit exists and is one keystroke. The user is never -required to fight the view in order to reach the geometry, and orbit is bound to -the gesture people actually try. - -> **Test.** Count camera manipulations in a representative modelling session. -> Any camera action the application could have performed for the user is a bug. - -### L9 — Accessible by construction, not by retrofit - -The floor, applied to every new interaction (details in §6.2): full keyboard -reach, no meaning carried by colour alone, hit targets that survive a shaky hand -and a HiDPI screen, legible labels over an arbitrary 3D background, no gesture -that depends on timing. - -> **Test.** Drive the whole interaction from the keyboard. Then drive it in -> greyscale. Both must work. - -### L10 — Vocabulary from the drawing office - -Names come from the language of people who make parts: fillet, chamfer, boss, -rib, counterbore, mate, exploded view. Not from the kernel (no "boolean -subtract", no "B-rep"), not from invented product-speak. Where the drawing-office -word and the beginner's word differ, use the drawing-office word and make the -tooltip teach it — an approachable tool that leaves the user unable to talk to a -machinist has failed them. - -> **Test.** Would a shop-floor engineer recognise this word? Would a first-time -> user be able to look it up and find a real definition? - -### L11 — The floor is a school laptop, and nothing is behind a door - -The product runs, completely, on a low-end laptop with integrated graphics and a -small screen, offline, with no account, no subscription and no feature withheld. -No capability in this document is reserved for a paid tier, a cloud service, a -plugin, or a machine with a discrete GPU — there is one product and everybody -gets all of it. - -> **Test.** On the reference low-end machine (§6.1), at 1366×768, with the -> network cable pulled and no account ever created: does this feature work, and -> is it usable at an honest frame rate? Any "no" is a defect, not a limitation. - -## 4. Interaction grammar — object-driven - -The rules above compose into one sentence the whole product obeys: - -> **Point at geometry → the geometry offers what can be done to it → choose the -> tool → manipulate handles and type exact values → confirm or cancel.** - -The selection does not merely feed the tool. **The selection determines which -tools exist.** Pick a planar face and the product shows you the small set of -things a planar face can become — sketch on it, extrude it, hole it, shell it, -put a datum on it. Pick an edge and that set is fillet, chamfer, and the sketch -tools that can use it as a reference. Nothing else is offered, because nothing -else is possible. - -This is the single largest thing we can do for a first-time user, and it is -worth stating as the reason: a beginner's difficulty is not operating a tool, -it is **not knowing which tools apply to what they are looking at**. A palette -of sixty icons answers a question they cannot yet ask. A face that offers its -own five verbs teaches the model of the product by using it. It also removes an -entire class of failure — a tool that silently does nothing because the -selection was wrong can no longer be reached. - -### 4.1 The offer, and the one thing that makes it work - -The flow, in full: - -> **left-click the geometry to select it → right-click to open the offer → a -> vertical list, always in the same order, each row an icon, a name and its -> keyboard shortcut → click.** - -- **Selecting and acting are separate gestures.** Left-click only ever selects, - so pointing at things is quiet — nothing pops up while you look around. - Right-click on the selection opens the offer, at the pointer, over the - geometry it acts on. -- **Order is fixed and it is the whole point.** A verb occupies one permanent - row, and that row is the same in every selection where the verb appears. - Dress-up is the fourth row on an edge, on a face, on a body, on the day the - product ships and two years later. The hand learns the position; the eye stops - being needed. -- **What does not apply is DISABLED IN PLACE, never removed.** This is the - single strongest thing the list does, and it is why it beat the radial we - drew first: a greyed row still carries its name *and the reason it is grey* — - "Create a sketch, or pick a solid face, first", "Create a solid body to - pattern first" — in the words the product already ships. On a first-run - document the offer is therefore not a mostly-empty control but a map of what - the product does and what you have to do first. -- **It is an accelerator, not a toll gate.** The toolbar and the single-letter - shortcuts keep working exactly as they do now, and pressing a tool directly - consumes the same selection (L3). An expert never has to open the offer; a - beginner never has to know the toolbar exists. Both routes land in the same - place — this is the only way one interface serves §2's three audiences. -- **Every row shows its keyboard shortcut**, right-aligned so the keys stack - into a column the eye learns without trying, beside the icon and the - drawing-office word (L10). This is deliberate: the offer is the path by which - a user stops needing the offer. You reach for fillet in its row, the row says - "F", and one day your hand types F before the menu has finished opening. A - menu that teaches its own shortcut is how a beginner becomes the power user - who never opens it — the same interface at two speeds, with no "advanced mode" - between them (§7). -- **A family with more than one applicable verb opens a submenu** to the side, - in its own fixed order. A family with exactly one shows that verb directly, so - the common path is never one click longer than it needs to be. -- **It never blocks the view of what it acts on**: it opens beside the pick, - never over it, with a thin leader back to the point it belongs to, and it - dismisses the moment the selection changes. -- **The header names what is selected** ("Top face · Body 1"), because a user - who mis-picked should find that out before choosing a verb, not after. - -#### Opening the offer on every machine - -Right-click is the primary gesture and every platform must have a first-class -equivalent — this is a reach requirement (L11), not a nicety: - -| Input | Gesture | -|---|---| -| Two-button mouse | right-click | -| Trackpad | two-finger tap (the OS-standard secondary click) | -| macOS, one-button mouse | **long-press**, and Ctrl-click, which is the platform convention | -| Keyboard | the Menu key, or Shift+F10, on the current selection | -| Touch / pen | long-press | - -The long-press is an **additional** route, never the only one — §6.2 forbids -press-and-hold as a sole path to a function, and it stays forbidden. Every -opening gesture is reachable at least two ways on every platform, and the -keyboard route exists everywhere. A long-press must show that it is charging -(a growing ring under the finger) so a user who holds too briefly learns why -nothing happened rather than concluding the product is broken (L5). - -#### The row-constancy invariant - -This is the rule that has to survive every future feature, so it is written as -an invariant rather than as advice: - -> **Every verb has exactly one row index in the offer. That index is identical -> for every selection type in which the verb appears. Verbs that do not apply to -> the current selection are DISABLED IN PLACE, with their reason — the offer is -> never compacted, re-sorted or re-ordered. Adding a verb never changes the -> index of an existing one.** - -Two consequences the group must accept together with the invariant: - -- **No adaptive ordering. Ever.** Not most-used-first, not recently-used-first, - not per-selection frequency. An offer that rearranges itself to be helpful - destroys the only thing that made it fast, and it does so precisely for the - user who has just started to learn it. (Office 2000's adaptive menus are the - textbook case; they were removed.) -- **Greyed rows are the price, and they are cheap.** A compacted menu is shorter - and unlearnable. A constant one is a few rows longer, teaches while it waits, - and is memorised in a week. - -#### The map — RATIFIED 2026-07-31 - -The invariant is not negotiable, and as of 2026-07-31 neither is the assignment: -the row order below is **ratified**. It was argued once; it is not argued again. -Changing an index from here on is a breaking change to every user's muscle -memory and needs the group, not a pull request (§9 q12). - -Eight families, ordered so the sequence itself has a logic: material is created, -grows, is taken away, is refined, is repeated, is moved, is referred to, is -edited. - -| Row | Family | On a face | On an edge | On a body | On text/art | -|---|---|---|---|---|---| -| **1** | Create | Sketch on it | — | — | Edit text | -| **2** | Add material | Extrude, thicken | — | Combine, thicken | Extrude | -| **3** | Remove | Hole, shell | Thread | Shell, cut, split | — | -| **4** | Dress-up | Draft | Fillet, chamfer | Fillet, chamfer | — | -| **5** | Repeat | Pattern | Pattern along it | Pattern, mirror | Pattern | -| **6** | Transform | Align to, mate | — | Move, mate | Move, size | -| **7** | Reference | Plane, axis, measure | Axis, measure | Project, measure, mass | — | -| **8** | Modify | Delete face, edit | — | Edit, colour, delete | Replace art | - -A dash means the row is drawn greyed for that selection, with its reason. - -The authoritative version of this table is **`docs/ux/tool_atlas.json`**, which -carries all 52 verbs with their preconditions and their refusal strings, taken -from the code rather than from memory. Every state it produces — 20 selection -kinds × 2 document states, 40 primary menus and 73 submenus — is rendered by -`docs/ux/mockups/gen_offer_mockups.py` into `docs/ux/offer_atlas.html`. Read the -atlas before proposing a change to the map; the generator refuses to render an -address collision, so the map cannot silently rot. - -#### Rejected: the radial ring - -The first design put the eight families at eight compass points around the pick. -It is recorded here because it is a good idea that loses on evidence, and -someone will propose it again: - -- an inapplicable slot could only be drawn empty, and **an empty slot says - nothing** — the reason text above has nowhere to live; -- the measured fill was **3.45 of 8 slots**, so most of the control was blank - most of the time, and on a fresh document only two of eight were live; -- sketch-mode *Create* needs **nine** addresses; eight forced two primitives - behind a "More" slot, and a ninth position costs the 45° spacing that made the - ring worth having; -- long translated names do not fit around a circle, and screen readers and arrow - keys need bespoke handling a list gets for free; -- a 380 px disc over the model costs more on a 1366×768 screen than a 324 px - list beside it (§6.1). - -What it kept — equidistant targets and a future flick gesture — buys little in a -product whose experts live on the keyboard by design. - -### 4.2 Confirm and cancel are objects, not gestures - -The old rule — click empty space to commit — is withdrawn. It was an invisible -gesture with a destructive meaning: nothing on screen said it, and a stray click -committed a feature the user was still adjusting. That is exactly what L5 -forbids, and it is hostile to the audience §6.1 exists for. - -- **A pending feature carries a confirm/cancel puck**, attached to the geometry - it is editing, next to its handles: ✓ commits, ✗ discards. Enter and Escape - mirror them for the keyboard (L9). It is drawn where the user's attention - already is, and it is the only thing in the viewport that commits. -- **Empty space now means "clear the selection"** — the safe meaning, and the - same meaning everywhere. -- **This is not a dialog** (L4). It is two objects in the scene, on the - geometry, non-modal: the camera still orbits, the tree is still there, the - values are still editable while it waits. -- **Continuous tools do not ask.** Drawing a line, a rectangle, a circle commits - each entity as its own gesture completes — a ✓ per line would destroy the - inner loop. The puck belongs to *features* (extrude, fillet, hole, pattern, - mate) and to sketch edits that hold a pending state. Enter/Escape end a - continuous tool rather than confirming an entity. -- **Ambiguity resolves toward keeping work, never toward losing it.** Starting - another operation while a valid feature is pending commits it rather than - discarding it; if it is not valid, the product says why (L7) and keeps it - pending. Since undo reaches everything (§6.1), the recoverable direction is - always the right default. - -### 4.3 The rest of the grammar - -- **The status line is one imperative sentence** naming what the tool wants - next, and it names the target when the target came from a selection - ("Circle — click centre, then radius · on the picked face"). It is the - authoritative feedback surface for the armed tool; the toolbar is not. -- **Hover previews, click commits.** A hover shows the ghost of what a click - would do wherever this is cheap to compute. -- **Selection is persistent and visible** until consumed or cleared. A tool that - consumes a selection clears it, so the next feature cannot silently inherit it. -- **Every gesture is undoable**, and the feature tree is editable history, not a - log. Re-editing a feature re-enters the same on-geometry interaction that - created it — including its offer and its puck. - -## 5. Layout and screen budget - -The viewport is the application. Chrome is a tax on it. - -- **One toolbar**, contextual to the mode (model / sketch). Tools are grouped by - what they make, not by which subsystem implements them. -- **A left rail for the document, not for parameters**: feature tree, bodies, - variables. It answers "what exists", never "what value should this be". -- **No parameter panel.** Where one exists today it is technical debt with a - scheduled removal (§10). -- **Print context is ambient**, not a panel: the plate is visible in the design - space, and print-domain warnings appear on the geometry that will fail. -- **Nothing is added to permanent chrome without removing something**, or - demonstrating that the addition is used in the majority of sessions. -- **The budget is set by the smallest screen we serve**, 1366×768 (§6.1) — not - by the reviewer's monitor. Chrome that fits a 27-inch display and swallows a - laptop's has not fitted, it has just failed somewhere the author cannot see. - -## 6. Accessibility — reach first, then the assistive floor - -"Accessible" means two different things and the product owes both. §6.1 is about -**who can get in at all**; §6.2 is about **who can operate it once inside**. -Neither is a phase. Both are merge requirements. - -### 6.1 Reach — the door has to be open - -The premise of the whole project: someone with no money, no licence, no account, -no fast machine and no teacher can open this and make a real thing. Free -software on a school laptop is the only path to a CAD tool that reaches people -who were never going to be handed one. If a design decision quietly raises the -cost of entry, it has broken the premise, however elegant it is. - -- **The reference machine.** A 5-year-old laptop: dual/quad-core CPU, - **integrated graphics**, 8 GB RAM, **1366×768** screen, no discrete GPU. The - Design tab must be usable there, and any interaction that needs more is a - design failure to be solved, not a requirement to be documented. The GPU path - degrades gracefully to software rendering rather than refusing to start; the - viewport stays interactive while the kernel thinks. -- **1366×768 is the layout target, not the stretch case.** A form-heavy side - panel is not merely inelegant on that screen — it takes the model off it. - This is the second, independent argument for the whole of L1 and §5. -- **No account, no cloud, no connection.** The product works forever with the - network unplugged. Nothing is uploaded, no sign-in gates any feature, no - telemetry is required to use it. A school network that blocks everything must - not be able to block this. -- **No tier, no plugin wall, no "pro".** Every feature named in this document is - in the product everyone downloads. Assemblies and exploded views are not the - paid half. -- **Files belong to the user**, on their disk, in a format that outlives the - project: the design travels inside the ordinary project file, and the geometry - exports to STEP and mesh formats anyone can open. -- **Learnable without instruction.** The first solid comes with no - documentation, no video and no tutorial mode — from noticing that a face can - be clicked. Tooltips teach the vocabulary (L10) at the moment it is needed; - nothing is explained in a manual the user will never open. -- **Plain language at the entry tier.** The Make tier speaks in words a - thirteen-year-old reads without stopping. Precision comes with the tier that - needs it, and everything is translated, because "accessible" in English only - is not accessible. -- **Exploration must be free.** Undo reaches everything, work is never lost to a - wrong click, and no dialog ever asks the user to be sure. A tool that punishes - experiments teaches people to stop experimenting, which is the one thing this - audience cannot afford to learn. -- **The product never blames the user.** Failures are stated as what happened - and what to do (L7). "Invalid input" is not an acceptable sentence anywhere. - -### 6.2 Assistive floor - -- **Keyboard**: every operation reachable and completable without a pointer. - Single-letter shortcuts for sketch tools, shown in the offer itself (§4.1) as - well as in the tooltip. The offer opens from the keyboard (Menu key or - Shift+F10) and walks by arrow key and by type-ahead, so the row map works for - someone who never touches the pointer. A visible focus state on every - focusable element. No shortcut that only works while the pointer happens to be - over the canvas. -- **Colour**: never the sole carrier of meaning. Selection is colour *and* - outline; an error is colour *and* an icon *and* text. Verify in greyscale. -- **Contrast**: labels over the 3D viewport get a scrim or halo so 4.5:1 holds - against any background the model can produce, including a white body under a - white plate. -- **Targets**: handles and grips no smaller than 32 px at 100 % scale, scaling - with the OS factor; the grab tolerance is larger than the drawn glyph. -- **Timing**: no double-click-to-mean-something-else, no press-and-hold as the - only route to a function, no cycle that depends on repeated clicks - (see L5). The long-press that opens the offer on a one-button Mac and on touch - (§4.1) is explicitly an *additional* route — Ctrl-click, two-finger tap and - the keyboard all reach the same place — and it shows its own progress while - charging, so it never fails silently. -- **Motion**: animation is functional (showing where a thing went), never - decorative, and it respects the reduced-motion preference. -- **Text**: no fixed-width assumptions; the UI holds together in German and in - Chinese, at 125 % and 200 % scale. Every string routed through the normal - translation path. - -## 7. Depth without clutter — the three tiers - -Power for experts is delivered by **progressive disclosure of tools, never by -relocation of tools**. A tool that appears in a later tier is in the same place -it will always be; it is simply not shown yet. - -| Tier | Who | What appears | -|---|---|---| -| **Make** | first hour | Sketch, extrude, revolve, hole, fillet/chamfer, move, commit to plate | -| **Model** | competent user | Patterns, shell, draft, sweep/loft, booleans, reference geometry, variables, import/export | -| **Mechanism** | mechanical designer | Assemblies and mates, exploded views, interference detection, surfaces, feature-level editing of imported solids | - -Rules that keep this honest: - -1. **Tiers are non-modal.** No mode switch, no workbench selector, no "advanced - mode" toggle that changes the meaning of anything. The tier only governs what - is *offered*. -2. **A tier reveals itself by use.** Using a body reveals boolean tools; adding - a second body reveals assembly tools. The product notices what you are doing. -3. **Nothing moves when a tier appears.** A user who learned where fillet lives - finds it in the same place forever. -4. **An expert tool obeys the same grammar** as a beginner tool. Mates are - picked in 3D like everything else, not configured in a table. -5. **Exploded views are a view state**, not a document mode — reversible, - draggable along mate axes, and never a separate file. - -## 8. Designing for print — the home advantage - -Design-time knowledge the application already has, and must use: - -- **The plate is present** in the design space, at the real size, with the real - origin. Committing a body to the plate is one action and preserves placement. -- **Print-domain checks run on the model, on the geometry, before slicing**: - walls thinner than the nozzle, unsupported overhangs beyond the material's - angle, features smaller than the layer height, a part that does not fit the - build volume. -- **These are warnings on the geometry, never a report.** The thin wall glows; - the tooltip says how thin and what the nozzle is. -- **Material and machine context is inherited** from the active slicer profile, - not re-entered in the Design tab. -- **The round trip is preserved**: editing a design after slicing returns to the - feature history, not to a mesh. - -## 9. The review gate - -Every pull request that touches the Design tab UI answers these, in the PR body. -A "no" that is not accompanied by an argument is a request for changes. - -1. Which law (L1–L11) does the change most directly serve? -2. Can the whole operation be completed without the pointer leaving the - viewport? If not, why is this the exception? - And: does the relevant selection *offer* this tool (§4.1), or must the user - already know it exists? -3. Are the values draggable *and* typable? -4. Screenshot of the state after **exactly one** click of the new gesture, - performed as a first-time user. -5. Keyboard-only walkthrough: does it complete? -6. Greyscale screenshot: is every state still distinguishable? -7. What was **removed**? (Net additions to permanent chrome require an argument.) -8. Which tier does it belong to, and does it appear without moving anything else? -9. What does it do when the geometry is invalid, and is that reported before the - commit? -10. Interaction cost: actions required for the canonical task it addresses, - before and after. -11. Reach (L11): screenshot at 1366×768 with the panel open — is the model still - on screen? Does it run on integrated graphics? Does it need the network, an - account, or a file the user cannot keep? -12. If the change adds or moves a verb in the offer: which row, and is it that - verb's row in **every** selection where it appears? Did any existing verb's - index change? (If yes, this is not a UI change, it is a breaking change to - every user's muscle memory, and it needs the group — see §4.1.) Was - `docs/ux/tool_atlas.json` updated and the atlas regenerated? -13. If the change adds a pointer gesture: what is its keyboard equivalent, and - what does a one-button Mac, a trackpad and a touch screen do (§4.1)? - -## 10. Where we stand today — honest inventory - -Complying with the laws already: - -- Sketch inline editors — draw an entity and its dimension tab opens on the - geometry; Tab walks Length → Width → Angle. -- Fillet/chamfer draggable radius arrow with an editable value label. -- Extrude depth arrow; move-body three-axis arrows. -- Datum-plane resize handles and offset arrow; ghost reference planes picked in - 3D. -- Imported-art place/size gizmo. -- Sketch plane taken from the picked face, with the target named in the status - line, and the sketch-plane dropdown deleted outright. - -Violating them, with removal scheduled: - -- **Every tool card is a two-column form** of combos and spin fields in the left - panel. This is the single largest debt in the product and the reason this - document exists. Tracked as an epic; each card is replaced by its on-geometry - equivalent, not improved in place. It fails L1 and it fails L11 twice over — - on a 1366×768 screen the cards leave the model a strip. -- Seven remaining plane pickers still populate a combo instead of consuming a - viewport selection. -- Pattern has no on-geometry spacing arrow or count badge. -- Hole is positioned by X/Y fields rather than by a point on a face. -- Booleans and cuts pick their operands from lists rather than in 3D. -- Fillet/chamfer edge selection still requires the click cycle L5 forbids. -- **Selecting geometry offers nothing.** There is no contextual offer (§4.1): - the user faces the full toolbar whatever they have picked, and finds out that - a tool did not apply by it doing nothing. This is the largest single item of - new work the charter asks for. The map and every state of it are already - drawn (`docs/ux/offer_atlas.html`); what the group owes itself before the code - is ratifying the row order, since every verb built before that lands has to be - addressed afterwards anyway. -- **Committing is an invisible click in empty space** rather than the - confirm/cancel puck of §4.2 — the exact gesture that rule withdraws. - -Nothing on the violating list is defended. The only open question for each is -what its on-geometry replacement should be. - -## 11. How the group works - -**Roles.** Product/UX lead (owns this document and casts the tie-break vote on -interaction questions); kernel maintainer; GUI maintainer; a print-domain -reviewer; a mechanical-design reviewer who uses the product on real work; an -accessibility reviewer covering both senses of §6 — reach and assistive — who -owns the reference machine and actually runs on it. One person may hold more -than one role; the UX lead and the mechanical-design reviewer should not be the -same person, and nobody reviews reach from a workstation. - -**The absent audience needs a seat.** The fourteen-year-old is not in the room -and cannot file an issue. Someone in the group is accountable for B5 and B6, and -the group watches real first-timers use the product on the reference machine at -least once a quarter — school, makerspace, or a friend's kid. Everything else in -this document can be argued from principle; approachability can only be -observed. - -**Cadence.** A short weekly review of open interaction proposals. A monthly pass -over the violating inventory in §10 — anything that has not moved in two months -is either scheduled or explicitly accepted as permanent, with a reason written -into this document. - -**How a change moves.** - -1. *Problem* — a described user difficulty, ideally with an interaction-cost - measurement, never a solution in disguise. -2. *Sketch* — one or two on-geometry interaction proposals, drawn or described - as a gesture sequence. Reviewed against §3 before any code. -3. *Prototype* — built behind whatever the smallest safe path is, driven end to - end on a real display, and screenshotted at each state. -4. *Gate* — §9 answered in the PR. -5. *Merge*, then update §10. - -**Decisions are written down.** Any resolution that constrains future work is -appended to this document as a numbered law or as an accepted exception with its -reasoning. A decision that lives only in a call is not a decision. - -**How disagreements resolve.** Against the laws first. If the laws do not decide -it, the tie-break is the interaction cost measured on the canonical tasks in -§12; if that does not decide it, the UX lead chooses and records why. - -## 12. Canonical tasks — the benchmark - -The measure of every UX change is the cost of these five tasks. Each is timed and -counted (clicks, keystrokes, camera actions, mode switches) on the headless rig -and, periodically, with real users who have not seen the product. - -| # | Task | What it exercises | -|---|---|---| -| **B1** | Bracket: sketch an L, extrude, two holes, fillet the inside corner, send to plate | The inner loop | -| **B2** | Change a hole diameter and the plate thickness, six features deep, and rebuild | Parametric editability | -| **B3** | Take an imported STEP, delete a boss, close the face, thicken a wall to nozzle width | Direct editing + print awareness | -| **B4** | Two parts, one revolute mate, check interference, produce an exploded view | The Mechanism tier | -| **B5** | First-run: from opening the Design tab to a print-ready solid, no documentation | Approachability | -| **B6** | B1 again, on the reference machine at 1366×768, offline, on a fresh account-less install | Reach (L11) | - -Every task is run on the reference machine of §6.1, not on a workstation — a -number measured on a fast desktop describes an experience most of our users will -never have. B6 repeats the inner loop under the full entry conditions so that -reach is a measured quantity and not an intention. - -Targets are set once each task has been measured on the current build. B5's -target is expressed in minutes-to-first-solid **by someone who has never seen a -CAD program**, and it is the number this project is ultimately judged by. - ---- - -### Appendix — anti-patterns we have already paid for - -Kept because each cost real time and each is easy to reintroduce. - -- **The dropdown that grew a row.** Fixing "cannot sketch on a face" by adding a - "Face of Body 1" entry to a plane combo. It reads as a small fix and it is the - side-panel architecture reproducing itself. -- **The invisible first click.** Flyout buttons and pick cycles whose first click - changes nothing meaningful. Filed as bugs three separate times against working - code, and made a real bug look fixed when it was not. -- **The fix verified through a path the user will never take.** A face-sketch fix - confirmed by double-clicking to reach face level. Users click once. A fix - reachable only by an undiscoverable gesture is indistinguishable from no fix. -- **The wrong feedback surface.** Measuring an armed tool by the toolbar, which - never renders keyboard-armed state. The status line is the surface that - answers. -- **The silent success.** A cut that removed no material, reported as done. Now - an error naming the likely cause. diff --git a/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md b/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md deleted file mode 100644 index cc2d4b22aa..0000000000 --- a/docs/CAD/design/mate-connectors/BEAR_CONNECTOR_REVIEW.md +++ /dev/null @@ -1,169 +0,0 @@ -# BearConnector.step — examination - -> **Scope.** One file was supplied and it contains **one object: the male.** Everything below is -> measured from that single solid. Earlier drafts of this note reasoned about a female pocket and a -> mating pair — those objects were never supplied, so any statement about them was speculation and -> has been removed. The clearance, the fit, and the pocket's legibility are all **unassessed**. - -Measured, not eyeballed. Imported into the Design tab's own OpenCascade kernel -(`import_step` → one valid closed solid), topology queried, geometry checked numerically. -Flat drawing: `artifacts/shots/bear-flat.png`. Viewport: `artifacts/shots/bear-02-zoom.png`. - -**File:** AP242 Edition 2, ST-Developer. 1 `MANIFOLD_SOLID_BREP`, 1 `CLOSED_SHELL`. -**Size:** 83.06 × 66.69 × 17.27 mm. **Faces:** 30 — 24 planar + 6 cylindrical. -**Curves:** 69 lines + 12 circles. **No** splines, spheres, tori or cones. -**Relief:** only four Z levels — 0, 3.00, 10.66, 17.27. - ---- - -## What is right, and precisely so - -**The sloping ridge is implemented exactly as briefed.** From (0.00, 18.40, 17.27) to -(0.00, 46.72, 10.66): 28.3 mm long, 6.61 mm drop, **13.1° slope**, and both ends sit dead on -x = 0.00. It breaks 180° rotation on its own. - -**20.0° uniform draft on all four snout flanks**, identical to within 0.1°: -`(0,−0.94,0.342) (0.936,0.08,0.342) (0,0.94,0.342) (−0.936,0.08,0.342)`. That is a real, -deliberate lead-in — it self-centres into a matching pocket, and it demoulds and prints. - -**The eyes are exactly symmetric**: Ø9.87 at x = ±16.43, y = 48.01, matching to 0.01 mm. -Someone mirrored those on purpose. - -**The mating feature is extremely economical**: only **five edges** exist above the 3 mm plate — -the ridge plus two flank edges at each end. Base plate is exactly 3.00 mm. - -The low-poly constraint is honoured. All six cylinders are outline rounds and eye holes; none of -them is a mating surface. - ---- - -## The asymmetry is deliberate, and it is complete - -**Correction.** A first pass read the left/right differences as an unfinished mirror. That was wrong: -the asymmetry is intentional. Tested properly — every candidate self-symmetry, in the part's own -centred frame, with a generous 0.1 mm tolerance: - -| operation | edges mapped onto the part | -|---|---| -| identity | 81 / 81 — 100 % | -| mirror about x = 0 (left/right) | **0 / 81** | -| mirror about y = 0 (top/bottom) | **0 / 81** | -| rotate 180° about Z | **0 / 81** | -| rotate 90° about Z | **0 / 81** | -| mirror about the diagonal | **0 / 81** | - -**The symmetry group is trivial.** No rigid motion or reflection maps this part onto itself, so -**every partial view determines the orientation uniquely** — you never need to see the whole face to -know which way round it goes. That is the strongest possible result for a keying interface and it is -exactly what the earlier abstract glyph work kept failing to achieve: a symmetric shape seen at a -grazing angle, or half-occluded, gives an ambiguous read. - -### Does it let you GRASP the orientation? Measured, not asserted. - -Unique-in-principle and graspable-at-a-glance are different claims. The symmetry table proves the -first. For the second, the front-on picture (outline + eyes + mouth, filled) was rasterised and -compared against its own mirror and its own 180° rotation — the two ways a person can get it wrong. - -**By size** (percentage of pixels that differ): - -| width | vs mirror | vs rotated 180° | -|---|---|---| -| 16 px | 20.7 % | 26.0 % | -| 24 px | 21.9 % | 30.9 % | -| 32 px | 23.0 % | 28.1 % | -| 48 px | 22.4 % | 30.6 % | -| 80 px | 24.7 % | 31.0 % | -| 160 px | 23.6 % | 31.0 % | - -**The curve is flat.** The full signal is already there at 16 pixels and more resolution adds -nothing. That is the whole result: **the orientation cue lives at low spatial frequency**, carried by -the overall shape rather than by any detail. It therefore survives distance, blur, poor light, -peripheral vision, a small print and a low-resolution screen. It is the exact opposite of the abstract -disc glyph, whose roll cue was a small high-frequency feature and died at a grazing angle. - -**Partial views — a claim I made and then withdrew.** I ran a masked-window test and concluded that -a single quarter of the face was enough to read the orientation. **That test was invalid and the -conclusion is wrong.** It compared a window of the original against *the same window* of the mirrored -and rotated versions — which silently hands the observer the registration. It assumes you already -know that the patch you are looking at is the top-left quarter, which is exactly the thing you would -not know if you could only see a quarter. - -**You need to see the whole face.** The cues here are *relational*: the big ear only means something -next to the small ear, and the mouth offset only means something relative to the centreline. None of -them is self-locating. Whole-face is the operating condition, and the design should be judged and -used on that basis. - -That does not weaken the size result above, which always used the complete silhouette: the whole face -reads at 16 px. Needing all of it, and needing very little resolution of it, are compatible — and for -a part held in a hand, seeing all of it is the normal case. - -**The signal is allocated to the right risks.** The strongest cue (up to 41.7 %) guards against -inserting it upside down — the mistake people actually make. The weakest (~23 %) guards the mirror -case, which needs the part flipped over and which the protrusion already prevents mechanically. - -It also does mechanical work beyond the ridge. The ridge alone breaks 180° rotation; the asymmetric -outline additionally defeats the **mirrored-part** case — a mirror-image copy will not fit, so a -modelling or printing mirror is caught at assembly rather than three steps later. - -And for children specifically, a symmetric cartoon face reads as a mask; illustrators asymmetrise -deliberately so a face reads as a *character*. The asymmetry is earning its keep three ways at once. - -### What is worth keeping in mind anyway - -**The ears differ by 42 %** — left 8.33 mm wide (top y 65.68), right 11.81 mm (top y 66.69). Both -start at the same y = 60.79, so they read as a deliberate pair rather than an error. 42 % is well -above the perceptual threshold: you see it instantly. Good cue. - -**The mouth is a smirk** — x −21.93 … 0.00, centred at x = −10.96, stopping on the centreline. A -classic character device and a strong asymmetry. - -**The rounds are the best cue and the one safety question.** All four are on the left — Ø11.71 at -(−40.82, 7.38), Ø11.71 at (−34.76, 0.58), Ø10.00 at (−29.85, 60.83), Ø2.90 at (−26.70, 65.95) — and -the right side is entirely sharp. This is the *most locally readable* cue in the design: the ears -differ only by comparison (you must see both to know which is which), whereas a rounded corner tells -you "this is the left" from that corner alone, by eye **or by fingertip**. For children assembling by -feel that is the cue doing the real work. - -The tension is that "sharp" on a children's part is a hazard, and the obvious safety fix — round -everything — destroys the cue. The resolution is not round-vs-sharp but **large-vs-small radius**: -keep R≈6 on the left and give the right R≈1. R1 still reads and feels sharp locally, so the cue -survives, and the actual edge hazard goes away. That is the one recommendation that outlives the -correction. - -**One measurement that does not fit the story:** the outline is off-centre by **0.54 mm** (left reach -40.99, right reach 42.07). A deliberate cue should be unmissable; 0.54 mm is invisible. It is -probably a by-product of the other features rather than intent — worth a look, not a defect. - ---- - -## Two judgement calls, not defects - -**The snout is highest at the nose tip and slopes down toward the brow** — a real bear's muzzle -does the opposite. Anatomically it reads more like a beak or a horn than a snout. But mechanically -it is the better choice: the nose tip enters the pocket first and does the finding. Keep it if the -lead-in matters more than the likeness; flip it if "it must look like a bear" wins. - -**Only the male was supplied**, so the clearance, the fit and the pocket are unassessed. Nothing in -this note should be read as a judgement on them. - ---- - -## The strategic point, which is the real reason this design is good - -It gives orientation **a name**. "Ears up, nose down" needs no legend, no convention and no -documentation. Face recognition is the most robust pattern-matching humans have: it survives low -resolution, poor light, partial occlusion and peripheral vision. That is exactly the robustness the -abstract ridge key was reaching for, and here it comes for free. - -**One earlier objection does not transfer — noting it only so it is not carried over by mistake.** -In §8c of the design doc a female *pocket* measured as visually invisible — flat-shaded, a recess -reads as a blank rectangle — and I concluded male/female -is the wrong polarity cue. **That was a viewport finding, and it does not apply to a physical part.** -Nobody looks into the pocket of a toy; they feel it. For a part in a child's hands, male/female is -exactly the right polarity language. The earlier conclusion stands for the on-screen glyph and must -not be carried over to this. - -**The one rule to write down now:** the face and the key must never be allowed to disagree. People -will trust the face over the mechanics every time. Here they agree — ridge on the centreline, ears -up. If the face is ever restyled independently of the key, a user will orient by the bear and be -wrong. Tie them permanently, in the model and in whatever generates it. diff --git a/docs/CAD/design/mate-connectors/BearConnector_Cutter.step b/docs/CAD/design/mate-connectors/BearConnector_Cutter.step deleted file mode 100644 index c78e19e536..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Cutter.step +++ /dev/null @@ -1,998 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T12:46:26',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#958); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#229,#260,#497,#514,#531,#548,#565,#582,#599, - #616,#633,#650,#667,#684,#701,#718,#735,#747,#770,#794,#810,#822, - #839,#856,#878,#895,#912,#929,#946)); -#17 = ADVANCED_FACE('',(#18,#68,#79,#213),#224,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(19.029295926024,-0.2,-17.63009960955)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(16.626582997737,-0.2,-8.940188245231)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(19.849519003668,-0.2,-20.59660707692)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(22.059435554995,-0.2,-3.734519760785)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(17.698510515043,-0.2,-23.73280021221)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-3.734519760785)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(0.297084840953,-0.2,-3.734519760785)); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(1.,0.,0.)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-8.903751135252)); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(-21.72552223146,-0.2,-19.83215600037)); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.,0.,1.)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(4.383041634064E-04,-0.2,-8.903751615529)); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-5.279852300138,-0.2,-8.903751135252)); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(-1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.F.); -#63 = EDGE_CURVE('',#24,#56,#64,.T.); -#64 = LINE('',#65,#66); -#65 = CARTESIAN_POINT('',(4.347099726942,-0.2,-8.913277437397)); -#66 = VECTOR('',#67,1.); -#67 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#68 = FACE_BOUND('',#69,.F.); -#69 = EDGE_LOOP('',(#70)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#72,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(21.163799345768,-0.2,-48.00951684793)); -#74 = CIRCLE('',#75,4.735522705283); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(16.428276640485,-0.2,-48.00951684793)); -#77 = DIRECTION('',(-0.,1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = FACE_BOUND('',#80,.F.); -#80 = EDGE_LOOP('',(#81,#91,#100,#108,#116,#125,#133,#142,#150,#158,#166 - ,#174,#182,#190,#198,#206)); -#81 = ORIENTED_EDGE('',*,*,#82,.T.); -#82 = EDGE_CURVE('',#83,#85,#87,.T.); -#83 = VERTEX_POINT('',#84); -#84 = CARTESIAN_POINT('',(-27.86158468659,-0.2,-65.78852163128)); -#85 = VERTEX_POINT('',#86); -#86 = CARTESIAN_POINT('',(-29.08766684168,-0.2,-64.52156932717)); -#87 = LINE('',#88,#89); -#88 = CARTESIAN_POINT('',(-29.44004200272,-0.2,-64.15744811364)); -#89 = VECTOR('',#90,1.); -#90 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#91 = ORIENTED_EDGE('',*,*,#92,.F.); -#92 = EDGE_CURVE('',#93,#85,#95,.T.); -#93 = VERTEX_POINT('',#94); -#94 = CARTESIAN_POINT('',(-28.96712497021,-0.2,-57.16864680227)); -#95 = CIRCLE('',#96,5.2); -#96 = AXIS2_PLACEMENT_3D('',#97,#98,#99); -#97 = CARTESIAN_POINT('',(-25.35093464349,-0.2,-60.90537900045)); -#98 = DIRECTION('',(0.,-1.,0.)); -#99 = DIRECTION('',(-1.,0.,0.)); -#100 = ORIENTED_EDGE('',*,*,#101,.T.); -#101 = EDGE_CURVE('',#93,#102,#104,.T.); -#102 = VERTEX_POINT('',#103); -#103 = CARTESIAN_POINT('',(-26.93875323652,-0.2,-55.20570756731)); -#104 = LINE('',#105,#106); -#105 = CARTESIAN_POINT('',(-14.90185526362,-0.2,-43.55710346492)); -#106 = VECTOR('',#107,1.); -#107 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#108 = ORIENTED_EDGE('',*,*,#109,.T.); -#109 = EDGE_CURVE('',#102,#110,#112,.T.); -#110 = VERTEX_POINT('',#111); -#111 = CARTESIAN_POINT('',(-41.17904151244,-0.2,-10.52828909594)); -#112 = LINE('',#113,#114); -#113 = CARTESIAN_POINT('',(-32.39120436163,-0.2,-38.09921113329)); -#114 = VECTOR('',#115,1.); -#115 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#116 = ORIENTED_EDGE('',*,*,#117,.F.); -#117 = EDGE_CURVE('',#118,#110,#120,.T.); -#118 = VERTEX_POINT('',#119); -#119 = CARTESIAN_POINT('',(-39.69176606491,-0.2,-4.408923352436)); -#120 = CIRCLE('',#121,6.054044962965); -#121 = AXIS2_PLACEMENT_3D('',#122,#123,#124); -#122 = CARTESIAN_POINT('',(-35.41090981799,-0.2,-8.689779599357)); -#123 = DIRECTION('',(0.,-1.,0.)); -#124 = DIRECTION('',(-1.,0.,0.)); -#125 = ORIENTED_EDGE('',*,*,#126,.T.); -#126 = EDGE_CURVE('',#118,#127,#129,.T.); -#127 = VERTEX_POINT('',#128); -#128 = CARTESIAN_POINT('',(-36.85603142851,-0.2,-1.573188716044)); -#129 = LINE('',#130,#131); -#130 = CARTESIAN_POINT('',(-36.19319006079,-0.2,-0.910347348321)); -#131 = VECTOR('',#132,1.); -#132 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#133 = ORIENTED_EDGE('',*,*,#134,.F.); -#134 = EDGE_CURVE('',#135,#127,#137,.T.); -#135 = VERTEX_POINT('',#136); -#136 = CARTESIAN_POINT('',(-32.57517518159,-0.2,0.2)); -#137 = CIRCLE('',#138,6.054044962965); -#138 = AXIS2_PLACEMENT_3D('',#139,#140,#141); -#139 = CARTESIAN_POINT('',(-32.57517518159,-0.2,-5.854044962965)); -#140 = DIRECTION('',(0.,-1.,0.)); -#141 = DIRECTION('',(-1.,0.,0.)); -#142 = ORIENTED_EDGE('',*,*,#143,.T.); -#143 = EDGE_CURVE('',#135,#144,#146,.T.); -#144 = VERTEX_POINT('',#145); -#145 = CARTESIAN_POINT('',(35.082842712475,-0.2,0.2)); -#146 = LINE('',#147,#148); -#147 = CARTESIAN_POINT('',(-7.942265537672,-0.2,0.2)); -#148 = VECTOR('',#149,1.); -#149 = DIRECTION('',(1.,0.,0.)); -#150 = ORIENTED_EDGE('',*,*,#151,.F.); -#151 = EDGE_CURVE('',#152,#144,#154,.T.); -#152 = VERTEX_POINT('',#153); -#153 = CARTESIAN_POINT('',(42.298608189024,-0.2,-7.015765476549)); -#154 = LINE('',#155,#156); -#155 = CARTESIAN_POINT('',(36.596246576251,-0.2,-1.313403863776)); -#156 = VECTOR('',#157,1.); -#157 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#158 = ORIENTED_EDGE('',*,*,#159,.F.); -#159 = EDGE_CURVE('',#160,#152,#162,.T.); -#160 = VERTEX_POINT('',#161); -#161 = CARTESIAN_POINT('',(26.938753236523,-0.2,-55.20570756731)); -#162 = LINE('',#163,#164); -#163 = CARTESIAN_POINT('',(32.699020781567,-0.2,-37.13346923684)); -#164 = VECTOR('',#165,1.); -#165 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#166 = ORIENTED_EDGE('',*,*,#167,.F.); -#167 = EDGE_CURVE('',#168,#160,#170,.T.); -#168 = VERTEX_POINT('',#169); -#169 = CARTESIAN_POINT('',(32.703857168398,-0.2,-60.78483712899)); -#170 = LINE('',#171,#172); -#171 = CARTESIAN_POINT('',(16.008242280412,-0.2,-44.62779994931)); -#172 = VECTOR('',#173,1.); -#173 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#174 = ORIENTED_EDGE('',*,*,#175,.F.); -#175 = EDGE_CURVE('',#176,#168,#178,.T.); -#176 = VERTEX_POINT('',#177); -#177 = CARTESIAN_POINT('',(26.715163243538,-0.2,-66.97315781796)); -#178 = LINE('',#179,#180); -#179 = CARTESIAN_POINT('',(30.25240665457,-0.2,-63.31800414721)); -#180 = VECTOR('',#181,1.); -#181 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#182 = ORIENTED_EDGE('',*,*,#183,.F.); -#183 = EDGE_CURVE('',#184,#176,#186,.T.); -#184 = VERTEX_POINT('',#185); -#185 = CARTESIAN_POINT('',(20.532019001374,-0.2,-60.98947335481)); -#186 = LINE('',#187,#188); -#187 = CARTESIAN_POINT('',(9.922784884512,-0.2,-50.72247862452)); -#188 = VECTOR('',#189,1.); -#189 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#190 = ORIENTED_EDGE('',*,*,#191,.F.); -#191 = EDGE_CURVE('',#192,#184,#194,.T.); -#192 = VERTEX_POINT('',#193); -#193 = CARTESIAN_POINT('',(-20.53201900137,-0.2,-60.98947335481)); -#194 = LINE('',#195,#196); -#195 = CARTESIAN_POINT('',(5.354765181569,-0.2,-60.98947335481)); -#196 = VECTOR('',#197,1.); -#197 = DIRECTION('',(1.,0.,0.)); -#198 = ORIENTED_EDGE('',*,*,#199,.T.); -#199 = EDGE_CURVE('',#192,#200,#202,.T.); -#200 = VERTEX_POINT('',#201); -#201 = CARTESIAN_POINT('',(-25.53052705686,-0.2,-65.82673637491)); -#202 = LINE('',#203,#204); -#203 = CARTESIAN_POINT('',(-9.454421870603,-0.2,-50.26922436104)); -#204 = VECTOR('',#205,1.); -#205 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#206 = ORIENTED_EDGE('',*,*,#207,.F.); -#207 = EDGE_CURVE('',#83,#200,#208,.T.); -#208 = CIRCLE('',#209,1.648528137424); -#209 = AXIS2_PLACEMENT_3D('',#210,#211,#212); -#210 = CARTESIAN_POINT('',(-26.67694849991,-0.2,-64.64210018823)); -#211 = DIRECTION('',(0.,-1.,0.)); -#212 = DIRECTION('',(-1.,0.,0.)); -#213 = FACE_BOUND('',#214,.F.); -#214 = EDGE_LOOP('',(#215)); -#215 = ORIENTED_EDGE('',*,*,#216,.F.); -#216 = EDGE_CURVE('',#217,#217,#219,.T.); -#217 = VERTEX_POINT('',#218); -#218 = CARTESIAN_POINT('',(-11.6927539352,-0.2,-48.00951684793)); -#219 = CIRCLE('',#220,4.735522705283); -#220 = AXIS2_PLACEMENT_3D('',#221,#222,#223); -#221 = CARTESIAN_POINT('',(-16.42827664048,-0.2,-48.00951684793)); -#222 = DIRECTION('',(-0.,1.,0.)); -#223 = DIRECTION('',(1.,0.,0.)); -#224 = PLANE('',#225); -#225 = AXIS2_PLACEMENT_3D('',#226,#227,#228); -#226 = CARTESIAN_POINT('',(0.403056515455,-0.2,-33.34517655273)); -#227 = DIRECTION('',(0.,1.,0.)); -#228 = DIRECTION('',(1.,0.,0.)); -#229 = ADVANCED_FACE('',(#230),#255,.F.); -#230 = FACE_BOUND('',#231,.F.); -#231 = EDGE_LOOP('',(#232,#240,#241,#249)); -#232 = ORIENTED_EDGE('',*,*,#233,.T.); -#233 = EDGE_CURVE('',#234,#160,#236,.T.); -#234 = VERTEX_POINT('',#235); -#235 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#236 = LINE('',#237,#238); -#237 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#238 = VECTOR('',#239,1.); -#239 = DIRECTION('',(0.,-1.,0.)); -#240 = ORIENTED_EDGE('',*,*,#159,.T.); -#241 = ORIENTED_EDGE('',*,*,#242,.F.); -#242 = EDGE_CURVE('',#243,#152,#245,.T.); -#243 = VERTEX_POINT('',#244); -#244 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#245 = LINE('',#246,#247); -#246 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#247 = VECTOR('',#248,1.); -#248 = DIRECTION('',(0.,-1.,0.)); -#249 = ORIENTED_EDGE('',*,*,#250,.F.); -#250 = EDGE_CURVE('',#234,#243,#251,.T.); -#251 = LINE('',#252,#253); -#252 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#253 = VECTOR('',#254,1.); -#254 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#255 = PLANE('',#256); -#256 = AXIS2_PLACEMENT_3D('',#257,#258,#259); -#257 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#258 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#259 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#260 = ADVANCED_FACE('',(#261,#311,#322,#447,#481),#492,.T.); -#261 = FACE_BOUND('',#262,.T.); -#262 = EDGE_LOOP('',(#263,#273,#281,#289,#297,#305)); -#263 = ORIENTED_EDGE('',*,*,#264,.F.); -#264 = EDGE_CURVE('',#265,#267,#269,.T.); -#265 = VERTEX_POINT('',#266); -#266 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#267 = VERTEX_POINT('',#268); -#268 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#269 = LINE('',#270,#271); -#270 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#271 = VECTOR('',#272,1.); -#272 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#273 = ORIENTED_EDGE('',*,*,#274,.F.); -#274 = EDGE_CURVE('',#275,#265,#277,.T.); -#275 = VERTEX_POINT('',#276); -#276 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#277 = LINE('',#278,#279); -#278 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#279 = VECTOR('',#280,1.); -#280 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#281 = ORIENTED_EDGE('',*,*,#282,.F.); -#282 = EDGE_CURVE('',#283,#275,#285,.T.); -#283 = VERTEX_POINT('',#284); -#284 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#285 = LINE('',#286,#287); -#286 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#287 = VECTOR('',#288,1.); -#288 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#289 = ORIENTED_EDGE('',*,*,#290,.F.); -#290 = EDGE_CURVE('',#291,#283,#293,.T.); -#291 = VERTEX_POINT('',#292); -#292 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#293 = LINE('',#294,#295); -#294 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#295 = VECTOR('',#296,1.); -#296 = DIRECTION('',(1.,0.,0.)); -#297 = ORIENTED_EDGE('',*,*,#298,.F.); -#298 = EDGE_CURVE('',#299,#291,#301,.T.); -#299 = VERTEX_POINT('',#300); -#300 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#301 = LINE('',#302,#303); -#302 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#303 = VECTOR('',#304,1.); -#304 = DIRECTION('',(0.,0.,1.)); -#305 = ORIENTED_EDGE('',*,*,#306,.F.); -#306 = EDGE_CURVE('',#267,#299,#307,.T.); -#307 = LINE('',#308,#309); -#308 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#309 = VECTOR('',#310,1.); -#310 = DIRECTION('',(-1.,0.,0.)); -#311 = FACE_BOUND('',#312,.T.); -#312 = EDGE_LOOP('',(#313)); -#313 = ORIENTED_EDGE('',*,*,#314,.F.); -#314 = EDGE_CURVE('',#315,#315,#317,.T.); -#315 = VERTEX_POINT('',#316); -#316 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#317 = CIRCLE('',#318,4.735522705283); -#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321); -#319 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#320 = DIRECTION('',(-0.,1.,0.)); -#321 = DIRECTION('',(1.,0.,0.)); -#322 = FACE_BOUND('',#323,.T.); -#323 = EDGE_LOOP('',(#324,#334,#343,#351,#360,#368,#374,#375,#383,#391, - #399,#407,#415,#424,#432,#441)); -#324 = ORIENTED_EDGE('',*,*,#325,.T.); -#325 = EDGE_CURVE('',#326,#328,#330,.T.); -#326 = VERTEX_POINT('',#327); -#327 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#328 = VERTEX_POINT('',#329); -#329 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#330 = LINE('',#331,#332); -#331 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#332 = VECTOR('',#333,1.); -#333 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#334 = ORIENTED_EDGE('',*,*,#335,.F.); -#335 = EDGE_CURVE('',#336,#328,#338,.T.); -#336 = VERTEX_POINT('',#337); -#337 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#338 = CIRCLE('',#339,6.054044962965); -#339 = AXIS2_PLACEMENT_3D('',#340,#341,#342); -#340 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#341 = DIRECTION('',(0.,-1.,0.)); -#342 = DIRECTION('',(-1.,0.,0.)); -#343 = ORIENTED_EDGE('',*,*,#344,.T.); -#344 = EDGE_CURVE('',#336,#345,#347,.T.); -#345 = VERTEX_POINT('',#346); -#346 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#347 = LINE('',#348,#349); -#348 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#349 = VECTOR('',#350,1.); -#350 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#351 = ORIENTED_EDGE('',*,*,#352,.F.); -#352 = EDGE_CURVE('',#353,#345,#355,.T.); -#353 = VERTEX_POINT('',#354); -#354 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#355 = CIRCLE('',#356,6.054044962965); -#356 = AXIS2_PLACEMENT_3D('',#357,#358,#359); -#357 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#358 = DIRECTION('',(0.,-1.,0.)); -#359 = DIRECTION('',(-1.,0.,0.)); -#360 = ORIENTED_EDGE('',*,*,#361,.T.); -#361 = EDGE_CURVE('',#353,#362,#364,.T.); -#362 = VERTEX_POINT('',#363); -#363 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#364 = LINE('',#365,#366); -#365 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#366 = VECTOR('',#367,1.); -#367 = DIRECTION('',(1.,0.,0.)); -#368 = ORIENTED_EDGE('',*,*,#369,.F.); -#369 = EDGE_CURVE('',#243,#362,#370,.T.); -#370 = LINE('',#371,#372); -#371 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#372 = VECTOR('',#373,1.); -#373 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#374 = ORIENTED_EDGE('',*,*,#250,.F.); -#375 = ORIENTED_EDGE('',*,*,#376,.F.); -#376 = EDGE_CURVE('',#377,#234,#379,.T.); -#377 = VERTEX_POINT('',#378); -#378 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#379 = LINE('',#380,#381); -#380 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#381 = VECTOR('',#382,1.); -#382 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#383 = ORIENTED_EDGE('',*,*,#384,.F.); -#384 = EDGE_CURVE('',#385,#377,#387,.T.); -#385 = VERTEX_POINT('',#386); -#386 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#387 = LINE('',#388,#389); -#388 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#389 = VECTOR('',#390,1.); -#390 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#391 = ORIENTED_EDGE('',*,*,#392,.F.); -#392 = EDGE_CURVE('',#393,#385,#395,.T.); -#393 = VERTEX_POINT('',#394); -#394 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#395 = LINE('',#396,#397); -#396 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#397 = VECTOR('',#398,1.); -#398 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#399 = ORIENTED_EDGE('',*,*,#400,.F.); -#400 = EDGE_CURVE('',#401,#393,#403,.T.); -#401 = VERTEX_POINT('',#402); -#402 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#403 = LINE('',#404,#405); -#404 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#405 = VECTOR('',#406,1.); -#406 = DIRECTION('',(1.,0.,0.)); -#407 = ORIENTED_EDGE('',*,*,#408,.T.); -#408 = EDGE_CURVE('',#401,#409,#411,.T.); -#409 = VERTEX_POINT('',#410); -#410 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#411 = LINE('',#412,#413); -#412 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#413 = VECTOR('',#414,1.); -#414 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#415 = ORIENTED_EDGE('',*,*,#416,.F.); -#416 = EDGE_CURVE('',#417,#409,#419,.T.); -#417 = VERTEX_POINT('',#418); -#418 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#419 = CIRCLE('',#420,1.648528137424); -#420 = AXIS2_PLACEMENT_3D('',#421,#422,#423); -#421 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#422 = DIRECTION('',(0.,-1.,0.)); -#423 = DIRECTION('',(-1.,0.,0.)); -#424 = ORIENTED_EDGE('',*,*,#425,.T.); -#425 = EDGE_CURVE('',#417,#426,#428,.T.); -#426 = VERTEX_POINT('',#427); -#427 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#428 = LINE('',#429,#430); -#429 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#430 = VECTOR('',#431,1.); -#431 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#432 = ORIENTED_EDGE('',*,*,#433,.F.); -#433 = EDGE_CURVE('',#434,#426,#436,.T.); -#434 = VERTEX_POINT('',#435); -#435 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#436 = CIRCLE('',#437,5.2); -#437 = AXIS2_PLACEMENT_3D('',#438,#439,#440); -#438 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#439 = DIRECTION('',(0.,-1.,0.)); -#440 = DIRECTION('',(-1.,0.,0.)); -#441 = ORIENTED_EDGE('',*,*,#442,.T.); -#442 = EDGE_CURVE('',#434,#326,#443,.T.); -#443 = LINE('',#444,#445); -#444 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#445 = VECTOR('',#446,1.); -#446 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#447 = FACE_BOUND('',#448,.T.); -#448 = EDGE_LOOP('',(#449,#459,#467,#475)); -#449 = ORIENTED_EDGE('',*,*,#450,.F.); -#450 = EDGE_CURVE('',#451,#453,#455,.T.); -#451 = VERTEX_POINT('',#452); -#452 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#453 = VERTEX_POINT('',#454); -#454 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#455 = LINE('',#456,#457); -#456 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#457 = VECTOR('',#458,1.); -#458 = DIRECTION('',(-8.501532861635E-02,0.,-0.996379643459)); -#459 = ORIENTED_EDGE('',*,*,#460,.F.); -#460 = EDGE_CURVE('',#461,#451,#463,.T.); -#461 = VERTEX_POINT('',#462); -#462 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#463 = LINE('',#464,#465); -#464 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#465 = VECTOR('',#466,1.); -#466 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#467 = ORIENTED_EDGE('',*,*,#468,.F.); -#468 = EDGE_CURVE('',#469,#461,#471,.T.); -#469 = VERTEX_POINT('',#470); -#470 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#471 = LINE('',#472,#473); -#472 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#473 = VECTOR('',#474,1.); -#474 = DIRECTION('',(-8.501532861635E-02,0.,0.996379643459)); -#475 = ORIENTED_EDGE('',*,*,#476,.F.); -#476 = EDGE_CURVE('',#453,#469,#477,.T.); -#477 = LINE('',#478,#479); -#478 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#479 = VECTOR('',#480,1.); -#480 = DIRECTION('',(-1.,0.,0.)); -#481 = FACE_BOUND('',#482,.T.); -#482 = EDGE_LOOP('',(#483)); -#483 = ORIENTED_EDGE('',*,*,#484,.F.); -#484 = EDGE_CURVE('',#485,#485,#487,.T.); -#485 = VERTEX_POINT('',#486); -#486 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#487 = CIRCLE('',#488,4.735522705283); -#488 = AXIS2_PLACEMENT_3D('',#489,#490,#491); -#489 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#490 = DIRECTION('',(-0.,1.,0.)); -#491 = DIRECTION('',(1.,0.,0.)); -#492 = PLANE('',#493); -#493 = AXIS2_PLACEMENT_3D('',#494,#495,#496); -#494 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#495 = DIRECTION('',(0.,1.,0.)); -#496 = DIRECTION('',(1.,0.,0.)); -#497 = ADVANCED_FACE('',(#498),#509,.F.); -#498 = FACE_BOUND('',#499,.F.); -#499 = EDGE_LOOP('',(#500,#506,#507,#508)); -#500 = ORIENTED_EDGE('',*,*,#501,.F.); -#501 = EDGE_CURVE('',#168,#377,#502,.T.); -#502 = LINE('',#503,#504); -#503 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#504 = VECTOR('',#505,1.); -#505 = DIRECTION('',(0.,1.,0.)); -#506 = ORIENTED_EDGE('',*,*,#167,.T.); -#507 = ORIENTED_EDGE('',*,*,#233,.F.); -#508 = ORIENTED_EDGE('',*,*,#376,.F.); -#509 = PLANE('',#510); -#510 = AXIS2_PLACEMENT_3D('',#511,#512,#513); -#511 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#512 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#513 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#514 = ADVANCED_FACE('',(#515),#526,.F.); -#515 = FACE_BOUND('',#516,.F.); -#516 = EDGE_LOOP('',(#517,#523,#524,#525)); -#517 = ORIENTED_EDGE('',*,*,#518,.F.); -#518 = EDGE_CURVE('',#176,#385,#519,.T.); -#519 = LINE('',#520,#521); -#520 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#521 = VECTOR('',#522,1.); -#522 = DIRECTION('',(0.,1.,0.)); -#523 = ORIENTED_EDGE('',*,*,#175,.T.); -#524 = ORIENTED_EDGE('',*,*,#501,.T.); -#525 = ORIENTED_EDGE('',*,*,#384,.F.); -#526 = PLANE('',#527); -#527 = AXIS2_PLACEMENT_3D('',#528,#529,#530); -#528 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#529 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#530 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#531 = ADVANCED_FACE('',(#532),#543,.F.); -#532 = FACE_BOUND('',#533,.F.); -#533 = EDGE_LOOP('',(#534,#540,#541,#542)); -#534 = ORIENTED_EDGE('',*,*,#535,.T.); -#535 = EDGE_CURVE('',#393,#184,#536,.T.); -#536 = LINE('',#537,#538); -#537 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#538 = VECTOR('',#539,1.); -#539 = DIRECTION('',(0.,-1.,0.)); -#540 = ORIENTED_EDGE('',*,*,#183,.T.); -#541 = ORIENTED_EDGE('',*,*,#518,.T.); -#542 = ORIENTED_EDGE('',*,*,#392,.F.); -#543 = PLANE('',#544); -#544 = AXIS2_PLACEMENT_3D('',#545,#546,#547); -#545 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#546 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#547 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#548 = ADVANCED_FACE('',(#549),#560,.F.); -#549 = FACE_BOUND('',#550,.F.); -#550 = EDGE_LOOP('',(#551,#557,#558,#559)); -#551 = ORIENTED_EDGE('',*,*,#552,.F.); -#552 = EDGE_CURVE('',#192,#401,#553,.T.); -#553 = LINE('',#554,#555); -#554 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#555 = VECTOR('',#556,1.); -#556 = DIRECTION('',(0.,1.,0.)); -#557 = ORIENTED_EDGE('',*,*,#191,.T.); -#558 = ORIENTED_EDGE('',*,*,#535,.F.); -#559 = ORIENTED_EDGE('',*,*,#400,.F.); -#560 = PLANE('',#561); -#561 = AXIS2_PLACEMENT_3D('',#562,#563,#564); -#562 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#563 = DIRECTION('',(0.,0.,1.)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = ADVANCED_FACE('',(#566),#577,.T.); -#566 = FACE_BOUND('',#567,.T.); -#567 = EDGE_LOOP('',(#568,#574,#575,#576)); -#568 = ORIENTED_EDGE('',*,*,#569,.F.); -#569 = EDGE_CURVE('',#409,#200,#570,.T.); -#570 = LINE('',#571,#572); -#571 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#572 = VECTOR('',#573,1.); -#573 = DIRECTION('',(0.,-1.,0.)); -#574 = ORIENTED_EDGE('',*,*,#408,.F.); -#575 = ORIENTED_EDGE('',*,*,#552,.F.); -#576 = ORIENTED_EDGE('',*,*,#199,.T.); -#577 = PLANE('',#578); -#578 = AXIS2_PLACEMENT_3D('',#579,#580,#581); -#579 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#580 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#581 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#582 = ADVANCED_FACE('',(#583),#594,.T.); -#583 = FACE_BOUND('',#584,.T.); -#584 = EDGE_LOOP('',(#585,#591,#592,#593)); -#585 = ORIENTED_EDGE('',*,*,#586,.F.); -#586 = EDGE_CURVE('',#417,#83,#587,.T.); -#587 = LINE('',#588,#589); -#588 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#589 = VECTOR('',#590,1.); -#590 = DIRECTION('',(0.,-1.,0.)); -#591 = ORIENTED_EDGE('',*,*,#416,.T.); -#592 = ORIENTED_EDGE('',*,*,#569,.T.); -#593 = ORIENTED_EDGE('',*,*,#207,.F.); -#594 = CYLINDRICAL_SURFACE('',#595,1.648528137424); -#595 = AXIS2_PLACEMENT_3D('',#596,#597,#598); -#596 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#597 = DIRECTION('',(0.,-1.,0.)); -#598 = DIRECTION('',(-1.,0.,0.)); -#599 = ADVANCED_FACE('',(#600),#611,.T.); -#600 = FACE_BOUND('',#601,.T.); -#601 = EDGE_LOOP('',(#602,#608,#609,#610)); -#602 = ORIENTED_EDGE('',*,*,#603,.F.); -#603 = EDGE_CURVE('',#426,#85,#604,.T.); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,-1.,0.)); -#608 = ORIENTED_EDGE('',*,*,#425,.F.); -#609 = ORIENTED_EDGE('',*,*,#586,.T.); -#610 = ORIENTED_EDGE('',*,*,#82,.T.); -#611 = PLANE('',#612); -#612 = AXIS2_PLACEMENT_3D('',#613,#614,#615); -#613 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#614 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#615 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#616 = ADVANCED_FACE('',(#617),#628,.T.); -#617 = FACE_BOUND('',#618,.T.); -#618 = EDGE_LOOP('',(#619,#625,#626,#627)); -#619 = ORIENTED_EDGE('',*,*,#620,.F.); -#620 = EDGE_CURVE('',#434,#93,#621,.T.); -#621 = LINE('',#622,#623); -#622 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#623 = VECTOR('',#624,1.); -#624 = DIRECTION('',(0.,-1.,0.)); -#625 = ORIENTED_EDGE('',*,*,#433,.T.); -#626 = ORIENTED_EDGE('',*,*,#603,.T.); -#627 = ORIENTED_EDGE('',*,*,#92,.F.); -#628 = CYLINDRICAL_SURFACE('',#629,5.2); -#629 = AXIS2_PLACEMENT_3D('',#630,#631,#632); -#630 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#631 = DIRECTION('',(0.,-1.,0.)); -#632 = DIRECTION('',(-1.,0.,0.)); -#633 = ADVANCED_FACE('',(#634),#645,.T.); -#634 = FACE_BOUND('',#635,.T.); -#635 = EDGE_LOOP('',(#636,#642,#643,#644)); -#636 = ORIENTED_EDGE('',*,*,#637,.F.); -#637 = EDGE_CURVE('',#326,#102,#638,.T.); -#638 = LINE('',#639,#640); -#639 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#640 = VECTOR('',#641,1.); -#641 = DIRECTION('',(0.,-1.,0.)); -#642 = ORIENTED_EDGE('',*,*,#442,.F.); -#643 = ORIENTED_EDGE('',*,*,#620,.T.); -#644 = ORIENTED_EDGE('',*,*,#101,.T.); -#645 = PLANE('',#646); -#646 = AXIS2_PLACEMENT_3D('',#647,#648,#649); -#647 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#648 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#649 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#650 = ADVANCED_FACE('',(#651),#662,.T.); -#651 = FACE_BOUND('',#652,.T.); -#652 = EDGE_LOOP('',(#653,#659,#660,#661)); -#653 = ORIENTED_EDGE('',*,*,#654,.F.); -#654 = EDGE_CURVE('',#328,#110,#655,.T.); -#655 = LINE('',#656,#657); -#656 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#657 = VECTOR('',#658,1.); -#658 = DIRECTION('',(0.,-1.,0.)); -#659 = ORIENTED_EDGE('',*,*,#325,.F.); -#660 = ORIENTED_EDGE('',*,*,#637,.T.); -#661 = ORIENTED_EDGE('',*,*,#109,.T.); -#662 = PLANE('',#663); -#663 = AXIS2_PLACEMENT_3D('',#664,#665,#666); -#664 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#665 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#666 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#667 = ADVANCED_FACE('',(#668),#679,.T.); -#668 = FACE_BOUND('',#669,.T.); -#669 = EDGE_LOOP('',(#670,#676,#677,#678)); -#670 = ORIENTED_EDGE('',*,*,#671,.F.); -#671 = EDGE_CURVE('',#336,#118,#672,.T.); -#672 = LINE('',#673,#674); -#673 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#674 = VECTOR('',#675,1.); -#675 = DIRECTION('',(0.,-1.,0.)); -#676 = ORIENTED_EDGE('',*,*,#335,.T.); -#677 = ORIENTED_EDGE('',*,*,#654,.T.); -#678 = ORIENTED_EDGE('',*,*,#117,.F.); -#679 = CYLINDRICAL_SURFACE('',#680,6.054044962965); -#680 = AXIS2_PLACEMENT_3D('',#681,#682,#683); -#681 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#682 = DIRECTION('',(0.,-1.,0.)); -#683 = DIRECTION('',(-1.,0.,0.)); -#684 = ADVANCED_FACE('',(#685),#696,.T.); -#685 = FACE_BOUND('',#686,.T.); -#686 = EDGE_LOOP('',(#687,#693,#694,#695)); -#687 = ORIENTED_EDGE('',*,*,#688,.F.); -#688 = EDGE_CURVE('',#345,#127,#689,.T.); -#689 = LINE('',#690,#691); -#690 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#691 = VECTOR('',#692,1.); -#692 = DIRECTION('',(0.,-1.,0.)); -#693 = ORIENTED_EDGE('',*,*,#344,.F.); -#694 = ORIENTED_EDGE('',*,*,#671,.T.); -#695 = ORIENTED_EDGE('',*,*,#126,.T.); -#696 = PLANE('',#697); -#697 = AXIS2_PLACEMENT_3D('',#698,#699,#700); -#698 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#699 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#700 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#701 = ADVANCED_FACE('',(#702),#713,.T.); -#702 = FACE_BOUND('',#703,.T.); -#703 = EDGE_LOOP('',(#704,#710,#711,#712)); -#704 = ORIENTED_EDGE('',*,*,#705,.F.); -#705 = EDGE_CURVE('',#353,#135,#706,.T.); -#706 = LINE('',#707,#708); -#707 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#708 = VECTOR('',#709,1.); -#709 = DIRECTION('',(0.,-1.,0.)); -#710 = ORIENTED_EDGE('',*,*,#352,.T.); -#711 = ORIENTED_EDGE('',*,*,#688,.T.); -#712 = ORIENTED_EDGE('',*,*,#134,.F.); -#713 = CYLINDRICAL_SURFACE('',#714,6.054044962965); -#714 = AXIS2_PLACEMENT_3D('',#715,#716,#717); -#715 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#716 = DIRECTION('',(0.,-1.,0.)); -#717 = DIRECTION('',(-1.,0.,0.)); -#718 = ADVANCED_FACE('',(#719),#730,.T.); -#719 = FACE_BOUND('',#720,.T.); -#720 = EDGE_LOOP('',(#721,#727,#728,#729)); -#721 = ORIENTED_EDGE('',*,*,#722,.F.); -#722 = EDGE_CURVE('',#362,#144,#723,.T.); -#723 = LINE('',#724,#725); -#724 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#725 = VECTOR('',#726,1.); -#726 = DIRECTION('',(0.,-1.,0.)); -#727 = ORIENTED_EDGE('',*,*,#361,.F.); -#728 = ORIENTED_EDGE('',*,*,#705,.T.); -#729 = ORIENTED_EDGE('',*,*,#143,.T.); -#730 = PLANE('',#731); -#731 = AXIS2_PLACEMENT_3D('',#732,#733,#734); -#732 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#733 = DIRECTION('',(0.,0.,1.)); -#734 = DIRECTION('',(0.,-1.,0.)); -#735 = ADVANCED_FACE('',(#736),#742,.F.); -#736 = FACE_BOUND('',#737,.F.); -#737 = EDGE_LOOP('',(#738,#739,#740,#741)); -#738 = ORIENTED_EDGE('',*,*,#151,.T.); -#739 = ORIENTED_EDGE('',*,*,#722,.F.); -#740 = ORIENTED_EDGE('',*,*,#369,.F.); -#741 = ORIENTED_EDGE('',*,*,#242,.T.); -#742 = PLANE('',#743); -#743 = AXIS2_PLACEMENT_3D('',#744,#745,#746); -#744 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#745 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#746 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#747 = ADVANCED_FACE('',(#748),#765,.T.); -#748 = FACE_BOUND('',#749,.T.); -#749 = EDGE_LOOP('',(#750,#758,#764)); -#750 = ORIENTED_EDGE('',*,*,#751,.T.); -#751 = EDGE_CURVE('',#451,#752,#754,.T.); -#752 = VERTEX_POINT('',#753); -#753 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#754 = LINE('',#755,#756); -#755 = CARTESIAN_POINT('',(5.649679875255,3.602918464526,-13.21082950266 - )); -#756 = VECTOR('',#757,1.); -#757 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#758 = ORIENTED_EDGE('',*,*,#759,.T.); -#759 = EDGE_CURVE('',#752,#461,#760,.T.); -#760 = LINE('',#761,#762); -#761 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#762 = VECTOR('',#763,1.); -#763 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#764 = ORIENTED_EDGE('',*,*,#460,.T.); -#765 = PLANE('',#766); -#766 = AXIS2_PLACEMENT_3D('',#767,#768,#769); -#767 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-13.01628215822 - )); -#768 = DIRECTION('',(2.881637632171E-16,0.342020143326,0.939692620786)); -#769 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326) - ); -#770 = ADVANCED_FACE('',(#771),#789,.T.); -#771 = FACE_BOUND('',#772,.T.); -#772 = EDGE_LOOP('',(#773,#781,#782,#783)); -#773 = ORIENTED_EDGE('',*,*,#774,.T.); -#774 = EDGE_CURVE('',#775,#752,#777,.T.); -#775 = VERTEX_POINT('',#776); -#776 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#777 = LINE('',#778,#779); -#778 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#779 = VECTOR('',#780,1.); -#780 = DIRECTION('',(5.275122655166E-17,0.227455280238,0.97378852709)); -#781 = ORIENTED_EDGE('',*,*,#751,.F.); -#782 = ORIENTED_EDGE('',*,*,#450,.T.); -#783 = ORIENTED_EDGE('',*,*,#784,.T.); -#784 = EDGE_CURVE('',#453,#775,#785,.T.); -#785 = LINE('',#786,#787); -#786 = CARTESIAN_POINT('',(1.103762571829,7.940067898719,-47.92064259636 - )); -#787 = VECTOR('',#788,1.); -#788 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#789 = PLANE('',#790); -#790 = AXIS2_PLACEMENT_3D('',#791,#792,#793); -#791 = CARTESIAN_POINT('',(5.823691883056,3.068404028665,-13.45978839622 - )); -#792 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02)); -#793 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487824E-02) - ); -#794 = ADVANCED_FACE('',(#795),#805,.T.); -#795 = FACE_BOUND('',#796,.T.); -#796 = EDGE_LOOP('',(#797,#803,#804)); -#797 = ORIENTED_EDGE('',*,*,#798,.T.); -#798 = EDGE_CURVE('',#469,#775,#799,.T.); -#799 = LINE('',#800,#801); -#800 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#801 = VECTOR('',#802,1.); -#802 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#803 = ORIENTED_EDGE('',*,*,#784,.F.); -#804 = ORIENTED_EDGE('',*,*,#476,.T.); -#805 = PLANE('',#806); -#806 = AXIS2_PLACEMENT_3D('',#807,#808,#809); -#807 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-49.69378323641 - )); -#808 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#809 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#810 = ADVANCED_FACE('',(#811),#817,.T.); -#811 = FACE_BOUND('',#812,.T.); -#812 = EDGE_LOOP('',(#813,#814,#815,#816)); -#813 = ORIENTED_EDGE('',*,*,#468,.T.); -#814 = ORIENTED_EDGE('',*,*,#759,.F.); -#815 = ORIENTED_EDGE('',*,*,#774,.F.); -#816 = ORIENTED_EDGE('',*,*,#798,.F.); -#817 = PLANE('',#818); -#818 = AXIS2_PLACEMENT_3D('',#819,#820,#821); -#819 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#820 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#821 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487824E-02)); -#822 = ADVANCED_FACE('',(#823),#834,.F.); -#823 = FACE_BOUND('',#824,.F.); -#824 = EDGE_LOOP('',(#825,#831,#832,#833)); -#825 = ORIENTED_EDGE('',*,*,#826,.F.); -#826 = EDGE_CURVE('',#217,#485,#827,.T.); -#827 = LINE('',#828,#829); -#828 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#829 = VECTOR('',#830,1.); -#830 = DIRECTION('',(0.,1.,0.)); -#831 = ORIENTED_EDGE('',*,*,#216,.T.); -#832 = ORIENTED_EDGE('',*,*,#826,.T.); -#833 = ORIENTED_EDGE('',*,*,#484,.F.); -#834 = CYLINDRICAL_SURFACE('',#835,4.735522705283); -#835 = AXIS2_PLACEMENT_3D('',#836,#837,#838); -#836 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#837 = DIRECTION('',(0.,1.,0.)); -#838 = DIRECTION('',(1.,0.,0.)); -#839 = ADVANCED_FACE('',(#840),#851,.F.); -#840 = FACE_BOUND('',#841,.F.); -#841 = EDGE_LOOP('',(#842,#848,#849,#850)); -#842 = ORIENTED_EDGE('',*,*,#843,.F.); -#843 = EDGE_CURVE('',#72,#315,#844,.T.); -#844 = LINE('',#845,#846); -#845 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#846 = VECTOR('',#847,1.); -#847 = DIRECTION('',(0.,1.,0.)); -#848 = ORIENTED_EDGE('',*,*,#71,.T.); -#849 = ORIENTED_EDGE('',*,*,#843,.T.); -#850 = ORIENTED_EDGE('',*,*,#314,.F.); -#851 = CYLINDRICAL_SURFACE('',#852,4.735522705283); -#852 = AXIS2_PLACEMENT_3D('',#853,#854,#855); -#853 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#854 = DIRECTION('',(0.,1.,0.)); -#855 = DIRECTION('',(1.,0.,0.)); -#856 = ADVANCED_FACE('',(#857),#873,.F.); -#857 = FACE_BOUND('',#858,.F.); -#858 = EDGE_LOOP('',(#859,#865,#866,#872)); -#859 = ORIENTED_EDGE('',*,*,#860,.F.); -#860 = EDGE_CURVE('',#24,#265,#861,.T.); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(0.,1.,0.)); -#865 = ORIENTED_EDGE('',*,*,#63,.T.); -#866 = ORIENTED_EDGE('',*,*,#867,.T.); -#867 = EDGE_CURVE('',#56,#267,#868,.T.); -#868 = LINE('',#869,#870); -#869 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#870 = VECTOR('',#871,1.); -#871 = DIRECTION('',(0.,1.,0.)); -#872 = ORIENTED_EDGE('',*,*,#264,.F.); -#873 = PLANE('',#874); -#874 = AXIS2_PLACEMENT_3D('',#875,#876,#877); -#875 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#876 = DIRECTION('',(-2.191520817069E-03,0.,-0.999997598615)); -#877 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#878 = ADVANCED_FACE('',(#879),#890,.F.); -#879 = FACE_BOUND('',#880,.F.); -#880 = EDGE_LOOP('',(#881,#887,#888,#889)); -#881 = ORIENTED_EDGE('',*,*,#882,.T.); -#882 = EDGE_CURVE('',#48,#299,#883,.T.); -#883 = LINE('',#884,#885); -#884 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#885 = VECTOR('',#886,1.); -#886 = DIRECTION('',(0.,1.,0.)); -#887 = ORIENTED_EDGE('',*,*,#306,.F.); -#888 = ORIENTED_EDGE('',*,*,#867,.F.); -#889 = ORIENTED_EDGE('',*,*,#55,.T.); -#890 = PLANE('',#891); -#891 = AXIS2_PLACEMENT_3D('',#892,#893,#894); -#892 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#893 = DIRECTION('',(0.,0.,-1.)); -#894 = DIRECTION('',(0.,1.,0.)); -#895 = ADVANCED_FACE('',(#896),#907,.F.); -#896 = FACE_BOUND('',#897,.F.); -#897 = EDGE_LOOP('',(#898,#904,#905,#906)); -#898 = ORIENTED_EDGE('',*,*,#899,.T.); -#899 = EDGE_CURVE('',#40,#291,#900,.T.); -#900 = LINE('',#901,#902); -#901 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#902 = VECTOR('',#903,1.); -#903 = DIRECTION('',(0.,1.,0.)); -#904 = ORIENTED_EDGE('',*,*,#298,.F.); -#905 = ORIENTED_EDGE('',*,*,#882,.F.); -#906 = ORIENTED_EDGE('',*,*,#47,.T.); -#907 = PLANE('',#908); -#908 = AXIS2_PLACEMENT_3D('',#909,#910,#911); -#909 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#910 = DIRECTION('',(-1.,0.,0.)); -#911 = DIRECTION('',(0.,1.,0.)); -#912 = ADVANCED_FACE('',(#913),#924,.F.); -#913 = FACE_BOUND('',#914,.F.); -#914 = EDGE_LOOP('',(#915,#921,#922,#923)); -#915 = ORIENTED_EDGE('',*,*,#916,.T.); -#916 = EDGE_CURVE('',#32,#283,#917,.T.); -#917 = LINE('',#918,#919); -#918 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#919 = VECTOR('',#920,1.); -#920 = DIRECTION('',(0.,1.,0.)); -#921 = ORIENTED_EDGE('',*,*,#290,.F.); -#922 = ORIENTED_EDGE('',*,*,#899,.F.); -#923 = ORIENTED_EDGE('',*,*,#39,.T.); -#924 = PLANE('',#925); -#925 = AXIS2_PLACEMENT_3D('',#926,#927,#928); -#926 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#927 = DIRECTION('',(0.,0.,1.)); -#928 = DIRECTION('',(0.,-1.,0.)); -#929 = ADVANCED_FACE('',(#930),#941,.F.); -#930 = FACE_BOUND('',#931,.F.); -#931 = EDGE_LOOP('',(#932,#938,#939,#940)); -#932 = ORIENTED_EDGE('',*,*,#933,.T.); -#933 = EDGE_CURVE('',#22,#275,#934,.T.); -#934 = LINE('',#935,#936); -#935 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#936 = VECTOR('',#937,1.); -#937 = DIRECTION('',(0.,1.,0.)); -#938 = ORIENTED_EDGE('',*,*,#282,.F.); -#939 = ORIENTED_EDGE('',*,*,#916,.F.); -#940 = ORIENTED_EDGE('',*,*,#31,.T.); -#941 = PLANE('',#942); -#942 = AXIS2_PLACEMENT_3D('',#943,#944,#945); -#943 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#944 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#945 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#946 = ADVANCED_FACE('',(#947),#953,.F.); -#947 = FACE_BOUND('',#948,.F.); -#948 = EDGE_LOOP('',(#949,#950,#951,#952)); -#949 = ORIENTED_EDGE('',*,*,#21,.T.); -#950 = ORIENTED_EDGE('',*,*,#860,.T.); -#951 = ORIENTED_EDGE('',*,*,#274,.F.); -#952 = ORIENTED_EDGE('',*,*,#933,.F.); -#953 = PLANE('',#954); -#954 = AXIS2_PLACEMENT_3D('',#955,#956,#957); -#955 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#956 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#957 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#958 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#962)) GLOBAL_UNIT_ASSIGNED_CONTEXT -((#959,#960,#961)) REPRESENTATION_CONTEXT('Context #1', - '3D Context with UNIT and UNCERTAINTY') ); -#959 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#960 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#961 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#962 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-05),#959, - 'distance_accuracy_value','confusion accuracy'); -#963 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female.step b/docs/CAD/design/mate-connectors/BearConnector_Female.step deleted file mode 100644 index 18e31c4b47..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female.step +++ /dev/null @@ -1,1173 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T10:54:26',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#1118); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#57,#222,#246,#270,#287,#299,#330,#354,#378, - #402,#426,#451,#475,#500,#524,#548,#573,#597,#622,#646,#670,#687, - #817,#848,#872,#896,#920,#944,#961,#986,#1017,#1033,#1050,#1061, - #1086,#1100,#1109)); -#17 = ADVANCED_FACE('',(#18),#52,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.,0.,1.)); -#30 = ORIENTED_EDGE('',*,*,#31,.T.); -#31 = EDGE_CURVE('',#22,#32,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796) - ); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(0.,1.,0.)); -#38 = ORIENTED_EDGE('',*,*,#39,.T.); -#39 = EDGE_CURVE('',#32,#40,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,4.2)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796) - ); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.,0.,1.)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#24,#40,#48,.T.); -#48 = LINE('',#49,#50); -#49 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#50 = VECTOR('',#51,1.); -#51 = DIRECTION('',(0.,1.,0.)); -#52 = PLANE('',#53); -#53 = AXIS2_PLACEMENT_3D('',#54,#55,#56); -#54 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#55 = DIRECTION('',(1.,0.,0.)); -#56 = DIRECTION('',(0.,0.,1.)); -#57 = ADVANCED_FACE('',(#58,#83),#217,.F.); -#58 = FACE_BOUND('',#59,.F.); -#59 = EDGE_LOOP('',(#60,#68,#69,#77)); -#60 = ORIENTED_EDGE('',*,*,#61,.F.); -#61 = EDGE_CURVE('',#22,#62,#64,.T.); -#62 = VERTEX_POINT('',#63); -#63 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#64 = LINE('',#65,#66); -#65 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#66 = VECTOR('',#67,1.); -#67 = DIRECTION('',(1.,0.,0.)); -#68 = ORIENTED_EDGE('',*,*,#21,.T.); -#69 = ORIENTED_EDGE('',*,*,#70,.T.); -#70 = EDGE_CURVE('',#24,#71,#73,.T.); -#71 = VERTEX_POINT('',#72); -#72 = CARTESIAN_POINT('',(46.298608189024,0.,4.2)); -#73 = LINE('',#74,#75); -#74 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#75 = VECTOR('',#76,1.); -#76 = DIRECTION('',(1.,0.,0.)); -#77 = ORIENTED_EDGE('',*,*,#78,.F.); -#78 = EDGE_CURVE('',#62,#71,#79,.T.); -#79 = LINE('',#80,#81); -#80 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#81 = VECTOR('',#82,1.); -#82 = DIRECTION('',(0.,0.,1.)); -#83 = FACE_BOUND('',#84,.F.); -#84 = EDGE_LOOP('',(#85,#95,#103,#111,#119,#128,#136,#145,#153,#161,#170 - ,#178,#187,#195,#203,#211)); -#85 = ORIENTED_EDGE('',*,*,#86,.T.); -#86 = EDGE_CURVE('',#87,#89,#91,.T.); -#87 = VERTEX_POINT('',#88); -#88 = CARTESIAN_POINT('',(32.703857168398,0.,-60.78483712899)); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(26.938753236523,0.,-55.20570756731)); -#91 = LINE('',#92,#93); -#92 = CARTESIAN_POINT('',(13.567306766147,0.,-42.26560567724)); -#93 = VECTOR('',#94,1.); -#94 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#95 = ORIENTED_EDGE('',*,*,#96,.T.); -#96 = EDGE_CURVE('',#89,#97,#99,.T.); -#97 = VERTEX_POINT('',#98); -#98 = CARTESIAN_POINT('',(42.298608189024,0.,-7.015765476549)); -#99 = LINE('',#100,#101); -#100 = CARTESIAN_POINT('',(25.140315874087,-4.440892098501E-16, - -60.84811712245)); -#101 = VECTOR('',#102,1.); -#102 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#103 = ORIENTED_EDGE('',*,*,#104,.T.); -#104 = EDGE_CURVE('',#97,#105,#107,.T.); -#105 = VERTEX_POINT('',#106); -#106 = CARTESIAN_POINT('',(35.082842712475,0.,0.2)); -#107 = LINE('',#108,#109); -#108 = CARTESIAN_POINT('',(34.536239068456,0.,0.746603644019)); -#109 = VECTOR('',#110,1.); -#110 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#111 = ORIENTED_EDGE('',*,*,#112,.F.); -#112 = EDGE_CURVE('',#113,#105,#115,.T.); -#113 = VERTEX_POINT('',#114); -#114 = CARTESIAN_POINT('',(-32.57517518159,0.,0.2)); -#115 = LINE('',#116,#117); -#116 = CARTESIAN_POINT('',(-30.87627118587,0.,0.2)); -#117 = VECTOR('',#118,1.); -#118 = DIRECTION('',(1.,0.,0.)); -#119 = ORIENTED_EDGE('',*,*,#120,.T.); -#120 = EDGE_CURVE('',#113,#121,#123,.T.); -#121 = VERTEX_POINT('',#122); -#122 = CARTESIAN_POINT('',(-36.85603142851,0.,-1.573188716044)); -#123 = CIRCLE('',#124,6.054044962965); -#124 = AXIS2_PLACEMENT_3D('',#125,#126,#127); -#125 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#126 = DIRECTION('',(0.,-1.,0.)); -#127 = DIRECTION('',(-1.,0.,0.)); -#128 = ORIENTED_EDGE('',*,*,#129,.F.); -#129 = EDGE_CURVE('',#130,#121,#132,.T.); -#130 = VERTEX_POINT('',#131); -#131 = CARTESIAN_POINT('',(-39.69176606491,0.,-4.408923352436)); -#132 = LINE('',#133,#134); -#133 = CARTESIAN_POINT('',(-57.0671882012,0.,-21.78434548873)); -#134 = VECTOR('',#135,1.); -#135 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#136 = ORIENTED_EDGE('',*,*,#137,.T.); -#137 = EDGE_CURVE('',#130,#138,#140,.T.); -#138 = VERTEX_POINT('',#139); -#139 = CARTESIAN_POINT('',(-41.17904151244,0.,-10.52828909594)); -#140 = CIRCLE('',#141,6.054044962965); -#141 = AXIS2_PLACEMENT_3D('',#142,#143,#144); -#142 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#143 = DIRECTION('',(0.,-1.,0.)); -#144 = DIRECTION('',(-1.,0.,0.)); -#145 = ORIENTED_EDGE('',*,*,#146,.F.); -#146 = EDGE_CURVE('',#147,#138,#149,.T.); -#147 = VERTEX_POINT('',#148); -#148 = CARTESIAN_POINT('',(-26.93875323652,0.,-55.20570756731)); -#149 = LINE('',#150,#151); -#150 = CARTESIAN_POINT('',(-29.06259699304,-4.440892098501E-16, - -48.54236940733)); -#151 = VECTOR('',#152,1.); -#152 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#153 = ORIENTED_EDGE('',*,*,#154,.F.); -#154 = EDGE_CURVE('',#155,#147,#157,.T.); -#155 = VERTEX_POINT('',#156); -#156 = CARTESIAN_POINT('',(-28.96712497021,0.,-57.16864680227)); -#157 = LINE('',#158,#159); -#158 = CARTESIAN_POINT('',(-36.14667143517,0.,-64.11659091489)); -#159 = VECTOR('',#160,1.); -#160 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#161 = ORIENTED_EDGE('',*,*,#162,.T.); -#162 = EDGE_CURVE('',#155,#163,#165,.T.); -#163 = VERTEX_POINT('',#164); -#164 = CARTESIAN_POINT('',(-29.08766684168,0.,-64.52156932717)); -#165 = CIRCLE('',#166,5.2); -#166 = AXIS2_PLACEMENT_3D('',#167,#168,#169); -#167 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#168 = DIRECTION('',(0.,-1.,0.)); -#169 = DIRECTION('',(-1.,0.,0.)); -#170 = ORIENTED_EDGE('',*,*,#171,.F.); -#171 = EDGE_CURVE('',#172,#163,#174,.T.); -#172 = VERTEX_POINT('',#173); -#173 = CARTESIAN_POINT('',(-27.86158468659,0.,-65.78852163128)); -#174 = LINE('',#175,#176); -#175 = CARTESIAN_POINT('',(-31.12923147938,0.,-62.41195129628)); -#176 = VECTOR('',#177,1.); -#177 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#178 = ORIENTED_EDGE('',*,*,#179,.T.); -#179 = EDGE_CURVE('',#172,#180,#182,.T.); -#180 = VERTEX_POINT('',#181); -#181 = CARTESIAN_POINT('',(-25.53052705686,0.,-65.82673637491)); -#182 = CIRCLE('',#183,1.648528137424); -#183 = AXIS2_PLACEMENT_3D('',#184,#185,#186); -#184 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#185 = DIRECTION('',(0.,-1.,0.)); -#186 = DIRECTION('',(-1.,0.,0.)); -#187 = ORIENTED_EDGE('',*,*,#188,.F.); -#188 = EDGE_CURVE('',#189,#180,#191,.T.); -#189 = VERTEX_POINT('',#190); -#190 = CARTESIAN_POINT('',(-20.53201900137,0.,-60.98947335481)); -#191 = LINE('',#192,#193); -#192 = CARTESIAN_POINT('',(-30.69923804215,0.,-70.82871181101)); -#193 = VECTOR('',#194,1.); -#194 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#195 = ORIENTED_EDGE('',*,*,#196,.T.); -#196 = EDGE_CURVE('',#189,#197,#199,.T.); -#197 = VERTEX_POINT('',#198); -#198 = CARTESIAN_POINT('',(20.532019001374,0.,-60.98947335481)); -#199 = LINE('',#200,#201); -#200 = CARTESIAN_POINT('',(-17.57924046663,0.,-60.98947335481)); -#201 = VECTOR('',#202,1.); -#202 = DIRECTION('',(1.,0.,0.)); -#203 = ORIENTED_EDGE('',*,*,#204,.T.); -#204 = EDGE_CURVE('',#197,#205,#207,.T.); -#205 = VERTEX_POINT('',#206); -#206 = CARTESIAN_POINT('',(26.715163243538,0.,-66.97315781796)); -#207 = LINE('',#208,#209); -#208 = CARTESIAN_POINT('',(7.481849370247,-4.440892098501E-16, - -48.36028435244)); -#209 = VECTOR('',#210,1.); -#210 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#211 = ORIENTED_EDGE('',*,*,#212,.T.); -#212 = EDGE_CURVE('',#205,#87,#213,.T.); -#213 = LINE('',#214,#215); -#214 = CARTESIAN_POINT('',(9.75933652063,0.,-84.4941890519)); -#215 = VECTOR('',#216,1.); -#216 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#217 = PLANE('',#218); -#218 = AXIS2_PLACEMENT_3D('',#219,#220,#221); -#219 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#220 = DIRECTION('',(0.,1.,0.)); -#221 = DIRECTION('',(0.,0.,1.)); -#222 = ADVANCED_FACE('',(#223),#241,.T.); -#223 = FACE_BOUND('',#224,.T.); -#224 = EDGE_LOOP('',(#225,#226,#227,#235)); -#225 = ORIENTED_EDGE('',*,*,#47,.F.); -#226 = ORIENTED_EDGE('',*,*,#70,.T.); -#227 = ORIENTED_EDGE('',*,*,#228,.T.); -#228 = EDGE_CURVE('',#71,#229,#231,.T.); -#229 = VERTEX_POINT('',#230); -#230 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,4.2)); -#231 = LINE('',#232,#233); -#232 = CARTESIAN_POINT('',(46.298608189024,0.,4.2)); -#233 = VECTOR('',#234,1.); -#234 = DIRECTION('',(0.,1.,0.)); -#235 = ORIENTED_EDGE('',*,*,#236,.F.); -#236 = EDGE_CURVE('',#40,#229,#237,.T.); -#237 = LINE('',#238,#239); -#238 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,4.2)); -#239 = VECTOR('',#240,1.); -#240 = DIRECTION('',(1.,0.,0.)); -#241 = PLANE('',#242); -#242 = AXIS2_PLACEMENT_3D('',#243,#244,#245); -#243 = CARTESIAN_POINT('',(-45.46495478095,0.,4.2)); -#244 = DIRECTION('',(0.,0.,1.)); -#245 = DIRECTION('',(1.,0.,0.)); -#246 = ADVANCED_FACE('',(#247),#265,.T.); -#247 = FACE_BOUND('',#248,.T.); -#248 = EDGE_LOOP('',(#249,#257,#258,#259)); -#249 = ORIENTED_EDGE('',*,*,#250,.F.); -#250 = EDGE_CURVE('',#32,#251,#253,.T.); -#251 = VERTEX_POINT('',#252); -#252 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,-70.97315781796 - )); -#253 = LINE('',#254,#255); -#254 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#255 = VECTOR('',#256,1.); -#256 = DIRECTION('',(1.,0.,0.)); -#257 = ORIENTED_EDGE('',*,*,#39,.T.); -#258 = ORIENTED_EDGE('',*,*,#236,.T.); -#259 = ORIENTED_EDGE('',*,*,#260,.F.); -#260 = EDGE_CURVE('',#251,#229,#261,.T.); -#261 = LINE('',#262,#263); -#262 = CARTESIAN_POINT('',(46.298608189024,20.8572529153,-70.97315781796 - )); -#263 = VECTOR('',#264,1.); -#264 = DIRECTION('',(0.,0.,1.)); -#265 = PLANE('',#266); -#266 = AXIS2_PLACEMENT_3D('',#267,#268,#269); -#267 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#268 = DIRECTION('',(0.,1.,0.)); -#269 = DIRECTION('',(0.,0.,1.)); -#270 = ADVANCED_FACE('',(#271),#282,.F.); -#271 = FACE_BOUND('',#272,.F.); -#272 = EDGE_LOOP('',(#273,#274,#275,#281)); -#273 = ORIENTED_EDGE('',*,*,#31,.F.); -#274 = ORIENTED_EDGE('',*,*,#61,.T.); -#275 = ORIENTED_EDGE('',*,*,#276,.T.); -#276 = EDGE_CURVE('',#62,#251,#277,.T.); -#277 = LINE('',#278,#279); -#278 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#279 = VECTOR('',#280,1.); -#280 = DIRECTION('',(0.,1.,0.)); -#281 = ORIENTED_EDGE('',*,*,#250,.F.); -#282 = PLANE('',#283); -#283 = AXIS2_PLACEMENT_3D('',#284,#285,#286); -#284 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#285 = DIRECTION('',(0.,0.,1.)); -#286 = DIRECTION('',(1.,0.,0.)); -#287 = ADVANCED_FACE('',(#288),#294,.T.); -#288 = FACE_BOUND('',#289,.T.); -#289 = EDGE_LOOP('',(#290,#291,#292,#293)); -#290 = ORIENTED_EDGE('',*,*,#78,.F.); -#291 = ORIENTED_EDGE('',*,*,#276,.T.); -#292 = ORIENTED_EDGE('',*,*,#260,.T.); -#293 = ORIENTED_EDGE('',*,*,#228,.F.); -#294 = PLANE('',#295); -#295 = AXIS2_PLACEMENT_3D('',#296,#297,#298); -#296 = CARTESIAN_POINT('',(46.298608189024,0.,-70.97315781796)); -#297 = DIRECTION('',(1.,0.,0.)); -#298 = DIRECTION('',(0.,0.,1.)); -#299 = ADVANCED_FACE('',(#300),#325,.T.); -#300 = FACE_BOUND('',#301,.T.); -#301 = EDGE_LOOP('',(#302,#310,#311,#319)); -#302 = ORIENTED_EDGE('',*,*,#303,.F.); -#303 = EDGE_CURVE('',#87,#304,#306,.T.); -#304 = VERTEX_POINT('',#305); -#305 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#306 = LINE('',#307,#308); -#307 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#308 = VECTOR('',#309,1.); -#309 = DIRECTION('',(0.,1.,0.)); -#310 = ORIENTED_EDGE('',*,*,#86,.T.); -#311 = ORIENTED_EDGE('',*,*,#312,.F.); -#312 = EDGE_CURVE('',#313,#89,#315,.T.); -#313 = VERTEX_POINT('',#314); -#314 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#315 = LINE('',#316,#317); -#316 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#317 = VECTOR('',#318,1.); -#318 = DIRECTION('',(0.,-1.,0.)); -#319 = ORIENTED_EDGE('',*,*,#320,.F.); -#320 = EDGE_CURVE('',#304,#313,#321,.T.); -#321 = LINE('',#322,#323); -#322 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#323 = VECTOR('',#324,1.); -#324 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#325 = PLANE('',#326); -#326 = AXIS2_PLACEMENT_3D('',#327,#328,#329); -#327 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#328 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#329 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#330 = ADVANCED_FACE('',(#331),#349,.T.); -#331 = FACE_BOUND('',#332,.T.); -#332 = EDGE_LOOP('',(#333,#341,#342,#343)); -#333 = ORIENTED_EDGE('',*,*,#334,.F.); -#334 = EDGE_CURVE('',#205,#335,#337,.T.); -#335 = VERTEX_POINT('',#336); -#336 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#337 = LINE('',#338,#339); -#338 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#339 = VECTOR('',#340,1.); -#340 = DIRECTION('',(0.,1.,0.)); -#341 = ORIENTED_EDGE('',*,*,#212,.T.); -#342 = ORIENTED_EDGE('',*,*,#303,.T.); -#343 = ORIENTED_EDGE('',*,*,#344,.F.); -#344 = EDGE_CURVE('',#335,#304,#345,.T.); -#345 = LINE('',#346,#347); -#346 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#347 = VECTOR('',#348,1.); -#348 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#349 = PLANE('',#350); -#350 = AXIS2_PLACEMENT_3D('',#351,#352,#353); -#351 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#352 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#353 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#354 = ADVANCED_FACE('',(#355),#373,.T.); -#355 = FACE_BOUND('',#356,.T.); -#356 = EDGE_LOOP('',(#357,#365,#371,#372)); -#357 = ORIENTED_EDGE('',*,*,#358,.F.); -#358 = EDGE_CURVE('',#359,#335,#361,.T.); -#359 = VERTEX_POINT('',#360); -#360 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#361 = LINE('',#362,#363); -#362 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#363 = VECTOR('',#364,1.); -#364 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#365 = ORIENTED_EDGE('',*,*,#366,.T.); -#366 = EDGE_CURVE('',#359,#197,#367,.T.); -#367 = LINE('',#368,#369); -#368 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#369 = VECTOR('',#370,1.); -#370 = DIRECTION('',(0.,-1.,0.)); -#371 = ORIENTED_EDGE('',*,*,#204,.T.); -#372 = ORIENTED_EDGE('',*,*,#334,.T.); -#373 = PLANE('',#374); -#374 = AXIS2_PLACEMENT_3D('',#375,#376,#377); -#375 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#376 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#377 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#378 = ADVANCED_FACE('',(#379),#397,.T.); -#379 = FACE_BOUND('',#380,.T.); -#380 = EDGE_LOOP('',(#381,#389,#390,#391)); -#381 = ORIENTED_EDGE('',*,*,#382,.F.); -#382 = EDGE_CURVE('',#189,#383,#385,.T.); -#383 = VERTEX_POINT('',#384); -#384 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#385 = LINE('',#386,#387); -#386 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#387 = VECTOR('',#388,1.); -#388 = DIRECTION('',(0.,1.,0.)); -#389 = ORIENTED_EDGE('',*,*,#196,.T.); -#390 = ORIENTED_EDGE('',*,*,#366,.F.); -#391 = ORIENTED_EDGE('',*,*,#392,.F.); -#392 = EDGE_CURVE('',#383,#359,#393,.T.); -#393 = LINE('',#394,#395); -#394 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#395 = VECTOR('',#396,1.); -#396 = DIRECTION('',(1.,0.,0.)); -#397 = PLANE('',#398); -#398 = AXIS2_PLACEMENT_3D('',#399,#400,#401); -#399 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#400 = DIRECTION('',(0.,0.,1.)); -#401 = DIRECTION('',(0.,-1.,0.)); -#402 = ADVANCED_FACE('',(#403),#421,.F.); -#403 = FACE_BOUND('',#404,.F.); -#404 = EDGE_LOOP('',(#405,#413,#419,#420)); -#405 = ORIENTED_EDGE('',*,*,#406,.F.); -#406 = EDGE_CURVE('',#407,#180,#409,.T.); -#407 = VERTEX_POINT('',#408); -#408 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#409 = LINE('',#410,#411); -#410 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#411 = VECTOR('',#412,1.); -#412 = DIRECTION('',(0.,-1.,0.)); -#413 = ORIENTED_EDGE('',*,*,#414,.F.); -#414 = EDGE_CURVE('',#383,#407,#415,.T.); -#415 = LINE('',#416,#417); -#416 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#417 = VECTOR('',#418,1.); -#418 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#419 = ORIENTED_EDGE('',*,*,#382,.F.); -#420 = ORIENTED_EDGE('',*,*,#188,.T.); -#421 = PLANE('',#422); -#422 = AXIS2_PLACEMENT_3D('',#423,#424,#425); -#423 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#424 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#425 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#426 = ADVANCED_FACE('',(#427),#446,.F.); -#427 = FACE_BOUND('',#428,.F.); -#428 = EDGE_LOOP('',(#429,#437,#444,#445)); -#429 = ORIENTED_EDGE('',*,*,#430,.F.); -#430 = EDGE_CURVE('',#431,#172,#433,.T.); -#431 = VERTEX_POINT('',#432); -#432 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#433 = LINE('',#434,#435); -#434 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#435 = VECTOR('',#436,1.); -#436 = DIRECTION('',(0.,-1.,0.)); -#437 = ORIENTED_EDGE('',*,*,#438,.T.); -#438 = EDGE_CURVE('',#431,#407,#439,.T.); -#439 = CIRCLE('',#440,1.648528137424); -#440 = AXIS2_PLACEMENT_3D('',#441,#442,#443); -#441 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#442 = DIRECTION('',(0.,-1.,0.)); -#443 = DIRECTION('',(-1.,0.,0.)); -#444 = ORIENTED_EDGE('',*,*,#406,.T.); -#445 = ORIENTED_EDGE('',*,*,#179,.F.); -#446 = CYLINDRICAL_SURFACE('',#447,1.648528137424); -#447 = AXIS2_PLACEMENT_3D('',#448,#449,#450); -#448 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#449 = DIRECTION('',(0.,-1.,0.)); -#450 = DIRECTION('',(-1.,0.,0.)); -#451 = ADVANCED_FACE('',(#452),#470,.F.); -#452 = FACE_BOUND('',#453,.F.); -#453 = EDGE_LOOP('',(#454,#462,#468,#469)); -#454 = ORIENTED_EDGE('',*,*,#455,.F.); -#455 = EDGE_CURVE('',#456,#163,#458,.T.); -#456 = VERTEX_POINT('',#457); -#457 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#458 = LINE('',#459,#460); -#459 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#460 = VECTOR('',#461,1.); -#461 = DIRECTION('',(0.,-1.,0.)); -#462 = ORIENTED_EDGE('',*,*,#463,.F.); -#463 = EDGE_CURVE('',#431,#456,#464,.T.); -#464 = LINE('',#465,#466); -#465 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#466 = VECTOR('',#467,1.); -#467 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#468 = ORIENTED_EDGE('',*,*,#430,.T.); -#469 = ORIENTED_EDGE('',*,*,#171,.T.); -#470 = PLANE('',#471); -#471 = AXIS2_PLACEMENT_3D('',#472,#473,#474); -#472 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#473 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#474 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#475 = ADVANCED_FACE('',(#476),#495,.F.); -#476 = FACE_BOUND('',#477,.F.); -#477 = EDGE_LOOP('',(#478,#486,#493,#494)); -#478 = ORIENTED_EDGE('',*,*,#479,.F.); -#479 = EDGE_CURVE('',#480,#155,#482,.T.); -#480 = VERTEX_POINT('',#481); -#481 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#482 = LINE('',#483,#484); -#483 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#484 = VECTOR('',#485,1.); -#485 = DIRECTION('',(0.,-1.,0.)); -#486 = ORIENTED_EDGE('',*,*,#487,.T.); -#487 = EDGE_CURVE('',#480,#456,#488,.T.); -#488 = CIRCLE('',#489,5.2); -#489 = AXIS2_PLACEMENT_3D('',#490,#491,#492); -#490 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#491 = DIRECTION('',(0.,-1.,0.)); -#492 = DIRECTION('',(-1.,0.,0.)); -#493 = ORIENTED_EDGE('',*,*,#455,.T.); -#494 = ORIENTED_EDGE('',*,*,#162,.F.); -#495 = CYLINDRICAL_SURFACE('',#496,5.2); -#496 = AXIS2_PLACEMENT_3D('',#497,#498,#499); -#497 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#498 = DIRECTION('',(0.,-1.,0.)); -#499 = DIRECTION('',(-1.,0.,0.)); -#500 = ADVANCED_FACE('',(#501),#519,.F.); -#501 = FACE_BOUND('',#502,.F.); -#502 = EDGE_LOOP('',(#503,#511,#517,#518)); -#503 = ORIENTED_EDGE('',*,*,#504,.F.); -#504 = EDGE_CURVE('',#505,#147,#507,.T.); -#505 = VERTEX_POINT('',#506); -#506 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#507 = LINE('',#508,#509); -#508 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#509 = VECTOR('',#510,1.); -#510 = DIRECTION('',(0.,-1.,0.)); -#511 = ORIENTED_EDGE('',*,*,#512,.F.); -#512 = EDGE_CURVE('',#480,#505,#513,.T.); -#513 = LINE('',#514,#515); -#514 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#515 = VECTOR('',#516,1.); -#516 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#517 = ORIENTED_EDGE('',*,*,#479,.T.); -#518 = ORIENTED_EDGE('',*,*,#154,.T.); -#519 = PLANE('',#520); -#520 = AXIS2_PLACEMENT_3D('',#521,#522,#523); -#521 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#522 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#523 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#524 = ADVANCED_FACE('',(#525),#543,.F.); -#525 = FACE_BOUND('',#526,.F.); -#526 = EDGE_LOOP('',(#527,#535,#541,#542)); -#527 = ORIENTED_EDGE('',*,*,#528,.F.); -#528 = EDGE_CURVE('',#529,#138,#531,.T.); -#529 = VERTEX_POINT('',#530); -#530 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#531 = LINE('',#532,#533); -#532 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#533 = VECTOR('',#534,1.); -#534 = DIRECTION('',(0.,-1.,0.)); -#535 = ORIENTED_EDGE('',*,*,#536,.F.); -#536 = EDGE_CURVE('',#505,#529,#537,.T.); -#537 = LINE('',#538,#539); -#538 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#539 = VECTOR('',#540,1.); -#540 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#541 = ORIENTED_EDGE('',*,*,#504,.T.); -#542 = ORIENTED_EDGE('',*,*,#146,.T.); -#543 = PLANE('',#544); -#544 = AXIS2_PLACEMENT_3D('',#545,#546,#547); -#545 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#546 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#547 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#548 = ADVANCED_FACE('',(#549),#568,.F.); -#549 = FACE_BOUND('',#550,.F.); -#550 = EDGE_LOOP('',(#551,#559,#566,#567)); -#551 = ORIENTED_EDGE('',*,*,#552,.F.); -#552 = EDGE_CURVE('',#553,#130,#555,.T.); -#553 = VERTEX_POINT('',#554); -#554 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#555 = LINE('',#556,#557); -#556 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#557 = VECTOR('',#558,1.); -#558 = DIRECTION('',(0.,-1.,0.)); -#559 = ORIENTED_EDGE('',*,*,#560,.T.); -#560 = EDGE_CURVE('',#553,#529,#561,.T.); -#561 = CIRCLE('',#562,6.054044962965); -#562 = AXIS2_PLACEMENT_3D('',#563,#564,#565); -#563 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = DIRECTION('',(-1.,0.,0.)); -#566 = ORIENTED_EDGE('',*,*,#528,.T.); -#567 = ORIENTED_EDGE('',*,*,#137,.F.); -#568 = CYLINDRICAL_SURFACE('',#569,6.054044962965); -#569 = AXIS2_PLACEMENT_3D('',#570,#571,#572); -#570 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#571 = DIRECTION('',(0.,-1.,0.)); -#572 = DIRECTION('',(-1.,0.,0.)); -#573 = ADVANCED_FACE('',(#574),#592,.F.); -#574 = FACE_BOUND('',#575,.F.); -#575 = EDGE_LOOP('',(#576,#584,#590,#591)); -#576 = ORIENTED_EDGE('',*,*,#577,.F.); -#577 = EDGE_CURVE('',#578,#121,#580,.T.); -#578 = VERTEX_POINT('',#579); -#579 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#580 = LINE('',#581,#582); -#581 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#582 = VECTOR('',#583,1.); -#583 = DIRECTION('',(0.,-1.,0.)); -#584 = ORIENTED_EDGE('',*,*,#585,.F.); -#585 = EDGE_CURVE('',#553,#578,#586,.T.); -#586 = LINE('',#587,#588); -#587 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#588 = VECTOR('',#589,1.); -#589 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#590 = ORIENTED_EDGE('',*,*,#552,.T.); -#591 = ORIENTED_EDGE('',*,*,#129,.T.); -#592 = PLANE('',#593); -#593 = AXIS2_PLACEMENT_3D('',#594,#595,#596); -#594 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#595 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#596 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#597 = ADVANCED_FACE('',(#598),#617,.F.); -#598 = FACE_BOUND('',#599,.F.); -#599 = EDGE_LOOP('',(#600,#608,#615,#616)); -#600 = ORIENTED_EDGE('',*,*,#601,.F.); -#601 = EDGE_CURVE('',#602,#113,#604,.T.); -#602 = VERTEX_POINT('',#603); -#603 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,-1.,0.)); -#608 = ORIENTED_EDGE('',*,*,#609,.T.); -#609 = EDGE_CURVE('',#602,#578,#610,.T.); -#610 = CIRCLE('',#611,6.054044962965); -#611 = AXIS2_PLACEMENT_3D('',#612,#613,#614); -#612 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#613 = DIRECTION('',(0.,-1.,0.)); -#614 = DIRECTION('',(-1.,0.,0.)); -#615 = ORIENTED_EDGE('',*,*,#577,.T.); -#616 = ORIENTED_EDGE('',*,*,#120,.F.); -#617 = CYLINDRICAL_SURFACE('',#618,6.054044962965); -#618 = AXIS2_PLACEMENT_3D('',#619,#620,#621); -#619 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#620 = DIRECTION('',(0.,-1.,0.)); -#621 = DIRECTION('',(-1.,0.,0.)); -#622 = ADVANCED_FACE('',(#623),#641,.F.); -#623 = FACE_BOUND('',#624,.F.); -#624 = EDGE_LOOP('',(#625,#633,#639,#640)); -#625 = ORIENTED_EDGE('',*,*,#626,.F.); -#626 = EDGE_CURVE('',#627,#105,#629,.T.); -#627 = VERTEX_POINT('',#628); -#628 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#629 = LINE('',#630,#631); -#630 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#631 = VECTOR('',#632,1.); -#632 = DIRECTION('',(0.,-1.,0.)); -#633 = ORIENTED_EDGE('',*,*,#634,.F.); -#634 = EDGE_CURVE('',#602,#627,#635,.T.); -#635 = LINE('',#636,#637); -#636 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#637 = VECTOR('',#638,1.); -#638 = DIRECTION('',(1.,0.,0.)); -#639 = ORIENTED_EDGE('',*,*,#601,.T.); -#640 = ORIENTED_EDGE('',*,*,#112,.T.); -#641 = PLANE('',#642); -#642 = AXIS2_PLACEMENT_3D('',#643,#644,#645); -#643 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#644 = DIRECTION('',(0.,0.,1.)); -#645 = DIRECTION('',(0.,-1.,0.)); -#646 = ADVANCED_FACE('',(#647),#665,.T.); -#647 = FACE_BOUND('',#648,.T.); -#648 = EDGE_LOOP('',(#649,#657,#658,#659)); -#649 = ORIENTED_EDGE('',*,*,#650,.T.); -#650 = EDGE_CURVE('',#651,#97,#653,.T.); -#651 = VERTEX_POINT('',#652); -#652 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#653 = LINE('',#654,#655); -#654 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#655 = VECTOR('',#656,1.); -#656 = DIRECTION('',(0.,-1.,0.)); -#657 = ORIENTED_EDGE('',*,*,#104,.T.); -#658 = ORIENTED_EDGE('',*,*,#626,.F.); -#659 = ORIENTED_EDGE('',*,*,#660,.F.); -#660 = EDGE_CURVE('',#651,#627,#661,.T.); -#661 = LINE('',#662,#663); -#662 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#663 = VECTOR('',#664,1.); -#664 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#665 = PLANE('',#666); -#666 = AXIS2_PLACEMENT_3D('',#667,#668,#669); -#667 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#668 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#669 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#670 = ADVANCED_FACE('',(#671),#682,.T.); -#671 = FACE_BOUND('',#672,.T.); -#672 = EDGE_LOOP('',(#673,#679,#680,#681)); -#673 = ORIENTED_EDGE('',*,*,#674,.F.); -#674 = EDGE_CURVE('',#313,#651,#675,.T.); -#675 = LINE('',#676,#677); -#676 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#677 = VECTOR('',#678,1.); -#678 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#679 = ORIENTED_EDGE('',*,*,#312,.T.); -#680 = ORIENTED_EDGE('',*,*,#96,.T.); -#681 = ORIENTED_EDGE('',*,*,#650,.F.); -#682 = PLANE('',#683); -#683 = AXIS2_PLACEMENT_3D('',#684,#685,#686); -#684 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#685 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#686 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#687 = ADVANCED_FACE('',(#688,#738,#749,#767,#801),#812,.F.); -#688 = FACE_BOUND('',#689,.F.); -#689 = EDGE_LOOP('',(#690,#700,#708,#716,#724,#732)); -#690 = ORIENTED_EDGE('',*,*,#691,.F.); -#691 = EDGE_CURVE('',#692,#694,#696,.T.); -#692 = VERTEX_POINT('',#693); -#693 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#694 = VERTEX_POINT('',#695); -#695 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#696 = LINE('',#697,#698); -#697 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#698 = VECTOR('',#699,1.); -#699 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#700 = ORIENTED_EDGE('',*,*,#701,.F.); -#701 = EDGE_CURVE('',#702,#692,#704,.T.); -#702 = VERTEX_POINT('',#703); -#703 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#704 = LINE('',#705,#706); -#705 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#706 = VECTOR('',#707,1.); -#707 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#708 = ORIENTED_EDGE('',*,*,#709,.F.); -#709 = EDGE_CURVE('',#710,#702,#712,.T.); -#710 = VERTEX_POINT('',#711); -#711 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#712 = LINE('',#713,#714); -#713 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#714 = VECTOR('',#715,1.); -#715 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#716 = ORIENTED_EDGE('',*,*,#717,.F.); -#717 = EDGE_CURVE('',#718,#710,#720,.T.); -#718 = VERTEX_POINT('',#719); -#719 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#720 = LINE('',#721,#722); -#721 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#722 = VECTOR('',#723,1.); -#723 = DIRECTION('',(1.,0.,0.)); -#724 = ORIENTED_EDGE('',*,*,#725,.F.); -#725 = EDGE_CURVE('',#726,#718,#728,.T.); -#726 = VERTEX_POINT('',#727); -#727 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#728 = LINE('',#729,#730); -#729 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#730 = VECTOR('',#731,1.); -#731 = DIRECTION('',(0.,0.,1.)); -#732 = ORIENTED_EDGE('',*,*,#733,.F.); -#733 = EDGE_CURVE('',#694,#726,#734,.T.); -#734 = LINE('',#735,#736); -#735 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#736 = VECTOR('',#737,1.); -#737 = DIRECTION('',(-1.,0.,0.)); -#738 = FACE_BOUND('',#739,.F.); -#739 = EDGE_LOOP('',(#740)); -#740 = ORIENTED_EDGE('',*,*,#741,.F.); -#741 = EDGE_CURVE('',#742,#742,#744,.T.); -#742 = VERTEX_POINT('',#743); -#743 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#744 = CIRCLE('',#745,4.735522705283); -#745 = AXIS2_PLACEMENT_3D('',#746,#747,#748); -#746 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#747 = DIRECTION('',(-0.,1.,0.)); -#748 = DIRECTION('',(1.,0.,0.)); -#749 = FACE_BOUND('',#750,.F.); -#750 = EDGE_LOOP('',(#751,#752,#753,#754,#755,#756,#757,#758,#759,#760, - #761,#762,#763,#764,#765,#766)); -#751 = ORIENTED_EDGE('',*,*,#536,.T.); -#752 = ORIENTED_EDGE('',*,*,#560,.F.); -#753 = ORIENTED_EDGE('',*,*,#585,.T.); -#754 = ORIENTED_EDGE('',*,*,#609,.F.); -#755 = ORIENTED_EDGE('',*,*,#634,.T.); -#756 = ORIENTED_EDGE('',*,*,#660,.F.); -#757 = ORIENTED_EDGE('',*,*,#674,.F.); -#758 = ORIENTED_EDGE('',*,*,#320,.F.); -#759 = ORIENTED_EDGE('',*,*,#344,.F.); -#760 = ORIENTED_EDGE('',*,*,#358,.F.); -#761 = ORIENTED_EDGE('',*,*,#392,.F.); -#762 = ORIENTED_EDGE('',*,*,#414,.T.); -#763 = ORIENTED_EDGE('',*,*,#438,.F.); -#764 = ORIENTED_EDGE('',*,*,#463,.T.); -#765 = ORIENTED_EDGE('',*,*,#487,.F.); -#766 = ORIENTED_EDGE('',*,*,#512,.T.); -#767 = FACE_BOUND('',#768,.F.); -#768 = EDGE_LOOP('',(#769,#779,#787,#795)); -#769 = ORIENTED_EDGE('',*,*,#770,.F.); -#770 = EDGE_CURVE('',#771,#773,#775,.T.); -#771 = VERTEX_POINT('',#772); -#772 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#773 = VERTEX_POINT('',#774); -#774 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#775 = LINE('',#776,#777); -#776 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#777 = VECTOR('',#778,1.); -#778 = DIRECTION('',(-8.501532861635E-02,0.,-0.996379643459)); -#779 = ORIENTED_EDGE('',*,*,#780,.F.); -#780 = EDGE_CURVE('',#781,#771,#783,.T.); -#781 = VERTEX_POINT('',#782); -#782 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#783 = LINE('',#784,#785); -#784 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#785 = VECTOR('',#786,1.); -#786 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#787 = ORIENTED_EDGE('',*,*,#788,.F.); -#788 = EDGE_CURVE('',#789,#781,#791,.T.); -#789 = VERTEX_POINT('',#790); -#790 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(-8.501532861635E-02,0.,0.996379643459)); -#795 = ORIENTED_EDGE('',*,*,#796,.F.); -#796 = EDGE_CURVE('',#773,#789,#797,.T.); -#797 = LINE('',#798,#799); -#798 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#799 = VECTOR('',#800,1.); -#800 = DIRECTION('',(-1.,0.,0.)); -#801 = FACE_BOUND('',#802,.F.); -#802 = EDGE_LOOP('',(#803)); -#803 = ORIENTED_EDGE('',*,*,#804,.F.); -#804 = EDGE_CURVE('',#805,#805,#807,.T.); -#805 = VERTEX_POINT('',#806); -#806 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#807 = CIRCLE('',#808,4.735522705283); -#808 = AXIS2_PLACEMENT_3D('',#809,#810,#811); -#809 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#810 = DIRECTION('',(-0.,1.,0.)); -#811 = DIRECTION('',(1.,0.,0.)); -#812 = PLANE('',#813); -#813 = AXIS2_PLACEMENT_3D('',#814,#815,#816); -#814 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#815 = DIRECTION('',(0.,1.,0.)); -#816 = DIRECTION('',(1.,0.,0.)); -#817 = ADVANCED_FACE('',(#818),#843,.T.); -#818 = FACE_BOUND('',#819,.T.); -#819 = EDGE_LOOP('',(#820,#828,#836,#842)); -#820 = ORIENTED_EDGE('',*,*,#821,.F.); -#821 = EDGE_CURVE('',#822,#692,#824,.T.); -#822 = VERTEX_POINT('',#823); -#823 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#824 = LINE('',#825,#826); -#825 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#826 = VECTOR('',#827,1.); -#827 = DIRECTION('',(0.,1.,0.)); -#828 = ORIENTED_EDGE('',*,*,#829,.T.); -#829 = EDGE_CURVE('',#822,#830,#832,.T.); -#830 = VERTEX_POINT('',#831); -#831 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#832 = LINE('',#833,#834); -#833 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#834 = VECTOR('',#835,1.); -#835 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#836 = ORIENTED_EDGE('',*,*,#837,.T.); -#837 = EDGE_CURVE('',#830,#694,#838,.T.); -#838 = LINE('',#839,#840); -#839 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#840 = VECTOR('',#841,1.); -#841 = DIRECTION('',(0.,1.,0.)); -#842 = ORIENTED_EDGE('',*,*,#691,.F.); -#843 = PLANE('',#844); -#844 = AXIS2_PLACEMENT_3D('',#845,#846,#847); -#845 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#846 = DIRECTION('',(-2.191520817069E-03,0.,-0.999997598615)); -#847 = DIRECTION('',(-0.999997598615,0.,2.191520817069E-03)); -#848 = ADVANCED_FACE('',(#849),#867,.T.); -#849 = FACE_BOUND('',#850,.T.); -#850 = EDGE_LOOP('',(#851,#859,#865,#866)); -#851 = ORIENTED_EDGE('',*,*,#852,.F.); -#852 = EDGE_CURVE('',#853,#702,#855,.T.); -#853 = VERTEX_POINT('',#854); -#854 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#855 = LINE('',#856,#857); -#856 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#857 = VECTOR('',#858,1.); -#858 = DIRECTION('',(0.,1.,0.)); -#859 = ORIENTED_EDGE('',*,*,#860,.T.); -#860 = EDGE_CURVE('',#853,#822,#861,.T.); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#865 = ORIENTED_EDGE('',*,*,#821,.T.); -#866 = ORIENTED_EDGE('',*,*,#701,.F.); -#867 = PLANE('',#868); -#868 = AXIS2_PLACEMENT_3D('',#869,#870,#871); -#869 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#870 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#871 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#872 = ADVANCED_FACE('',(#873),#891,.T.); -#873 = FACE_BOUND('',#874,.T.); -#874 = EDGE_LOOP('',(#875,#883,#884,#885)); -#875 = ORIENTED_EDGE('',*,*,#876,.T.); -#876 = EDGE_CURVE('',#877,#853,#879,.T.); -#877 = VERTEX_POINT('',#878); -#878 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#879 = LINE('',#880,#881); -#880 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#881 = VECTOR('',#882,1.); -#882 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#883 = ORIENTED_EDGE('',*,*,#852,.T.); -#884 = ORIENTED_EDGE('',*,*,#709,.F.); -#885 = ORIENTED_EDGE('',*,*,#886,.F.); -#886 = EDGE_CURVE('',#877,#710,#887,.T.); -#887 = LINE('',#888,#889); -#888 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#889 = VECTOR('',#890,1.); -#890 = DIRECTION('',(0.,1.,0.)); -#891 = PLANE('',#892); -#892 = AXIS2_PLACEMENT_3D('',#893,#894,#895); -#893 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#894 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#895 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#896 = ADVANCED_FACE('',(#897),#915,.T.); -#897 = FACE_BOUND('',#898,.T.); -#898 = EDGE_LOOP('',(#899,#907,#908,#909)); -#899 = ORIENTED_EDGE('',*,*,#900,.T.); -#900 = EDGE_CURVE('',#901,#877,#903,.T.); -#901 = VERTEX_POINT('',#902); -#902 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#903 = LINE('',#904,#905); -#904 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#905 = VECTOR('',#906,1.); -#906 = DIRECTION('',(1.,0.,0.)); -#907 = ORIENTED_EDGE('',*,*,#886,.T.); -#908 = ORIENTED_EDGE('',*,*,#717,.F.); -#909 = ORIENTED_EDGE('',*,*,#910,.F.); -#910 = EDGE_CURVE('',#901,#718,#911,.T.); -#911 = LINE('',#912,#913); -#912 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#913 = VECTOR('',#914,1.); -#914 = DIRECTION('',(0.,1.,0.)); -#915 = PLANE('',#916); -#916 = AXIS2_PLACEMENT_3D('',#917,#918,#919); -#917 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#918 = DIRECTION('',(0.,0.,1.)); -#919 = DIRECTION('',(0.,-1.,0.)); -#920 = ADVANCED_FACE('',(#921),#939,.T.); -#921 = FACE_BOUND('',#922,.T.); -#922 = EDGE_LOOP('',(#923,#931,#932,#933)); -#923 = ORIENTED_EDGE('',*,*,#924,.T.); -#924 = EDGE_CURVE('',#925,#901,#927,.T.); -#925 = VERTEX_POINT('',#926); -#926 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#927 = LINE('',#928,#929); -#928 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#929 = VECTOR('',#930,1.); -#930 = DIRECTION('',(0.,0.,1.)); -#931 = ORIENTED_EDGE('',*,*,#910,.T.); -#932 = ORIENTED_EDGE('',*,*,#725,.F.); -#933 = ORIENTED_EDGE('',*,*,#934,.F.); -#934 = EDGE_CURVE('',#925,#726,#935,.T.); -#935 = LINE('',#936,#937); -#936 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#937 = VECTOR('',#938,1.); -#938 = DIRECTION('',(0.,1.,0.)); -#939 = PLANE('',#940); -#940 = AXIS2_PLACEMENT_3D('',#941,#942,#943); -#941 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#942 = DIRECTION('',(-1.,0.,0.)); -#943 = DIRECTION('',(0.,1.,0.)); -#944 = ADVANCED_FACE('',(#945),#956,.T.); -#945 = FACE_BOUND('',#946,.T.); -#946 = EDGE_LOOP('',(#947,#953,#954,#955)); -#947 = ORIENTED_EDGE('',*,*,#948,.T.); -#948 = EDGE_CURVE('',#830,#925,#949,.T.); -#949 = LINE('',#950,#951); -#950 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#951 = VECTOR('',#952,1.); -#952 = DIRECTION('',(-1.,0.,0.)); -#953 = ORIENTED_EDGE('',*,*,#934,.T.); -#954 = ORIENTED_EDGE('',*,*,#733,.F.); -#955 = ORIENTED_EDGE('',*,*,#837,.F.); -#956 = PLANE('',#957); -#957 = AXIS2_PLACEMENT_3D('',#958,#959,#960); -#958 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#959 = DIRECTION('',(0.,0.,-1.)); -#960 = DIRECTION('',(0.,1.,0.)); -#961 = ADVANCED_FACE('',(#962),#981,.T.); -#962 = FACE_BOUND('',#963,.T.); -#963 = EDGE_LOOP('',(#964,#973,#979,#980)); -#964 = ORIENTED_EDGE('',*,*,#965,.T.); -#965 = EDGE_CURVE('',#966,#966,#968,.T.); -#966 = VERTEX_POINT('',#967); -#967 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#968 = CIRCLE('',#969,4.735522705283); -#969 = AXIS2_PLACEMENT_3D('',#970,#971,#972); -#970 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#971 = DIRECTION('',(-0.,1.,0.)); -#972 = DIRECTION('',(1.,0.,0.)); -#973 = ORIENTED_EDGE('',*,*,#974,.T.); -#974 = EDGE_CURVE('',#966,#742,#975,.T.); -#975 = LINE('',#976,#977); -#976 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#977 = VECTOR('',#978,1.); -#978 = DIRECTION('',(0.,1.,0.)); -#979 = ORIENTED_EDGE('',*,*,#741,.F.); -#980 = ORIENTED_EDGE('',*,*,#974,.F.); -#981 = CYLINDRICAL_SURFACE('',#982,4.735522705283); -#982 = AXIS2_PLACEMENT_3D('',#983,#984,#985); -#983 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#984 = DIRECTION('',(0.,1.,0.)); -#985 = DIRECTION('',(1.,0.,0.)); -#986 = ADVANCED_FACE('',(#987),#1012,.F.); -#987 = FACE_BOUND('',#988,.F.); -#988 = EDGE_LOOP('',(#989,#999,#1005,#1006)); -#989 = ORIENTED_EDGE('',*,*,#990,.T.); -#990 = EDGE_CURVE('',#991,#993,#995,.T.); -#991 = VERTEX_POINT('',#992); -#992 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#993 = VERTEX_POINT('',#994); -#994 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#995 = LINE('',#996,#997); -#996 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#997 = VECTOR('',#998,1.); -#998 = DIRECTION('',(5.275122655166E-17,0.227455280238,0.97378852709)); -#999 = ORIENTED_EDGE('',*,*,#1000,.F.); -#1000 = EDGE_CURVE('',#771,#993,#1001,.T.); -#1001 = LINE('',#1002,#1003); -#1002 = CARTESIAN_POINT('',(5.649679875255,3.602918464526, - -13.21082950266)); -#1003 = VECTOR('',#1004,1.); -#1004 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#1005 = ORIENTED_EDGE('',*,*,#770,.T.); -#1006 = ORIENTED_EDGE('',*,*,#1007,.T.); -#1007 = EDGE_CURVE('',#773,#991,#1008,.T.); -#1008 = LINE('',#1009,#1010); -#1009 = CARTESIAN_POINT('',(1.103762571829,7.940067898719, - -47.92064259636)); -#1010 = VECTOR('',#1011,1.); -#1011 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#1012 = PLANE('',#1013); -#1013 = AXIS2_PLACEMENT_3D('',#1014,#1015,#1016); -#1014 = CARTESIAN_POINT('',(5.823691883056,3.068404028665, - -13.45978839622)); -#1015 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1016 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487824E-02) - ); -#1017 = ADVANCED_FACE('',(#1018),#1028,.F.); -#1018 = FACE_BOUND('',#1019,.F.); -#1019 = EDGE_LOOP('',(#1020,#1021,#1027)); -#1020 = ORIENTED_EDGE('',*,*,#1000,.T.); -#1021 = ORIENTED_EDGE('',*,*,#1022,.T.); -#1022 = EDGE_CURVE('',#993,#781,#1023,.T.); -#1023 = LINE('',#1024,#1025); -#1024 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#1025 = VECTOR('',#1026,1.); -#1026 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#1027 = ORIENTED_EDGE('',*,*,#780,.T.); -#1028 = PLANE('',#1029); -#1029 = AXIS2_PLACEMENT_3D('',#1030,#1031,#1032); -#1030 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -13.01628215822)); -#1031 = DIRECTION('',(2.881637632171E-16,0.342020143326,0.939692620786) - ); -#1032 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326 - )); -#1033 = ADVANCED_FACE('',(#1034),#1045,.F.); -#1034 = FACE_BOUND('',#1035,.F.); -#1035 = EDGE_LOOP('',(#1036,#1037,#1038,#1039)); -#1036 = ORIENTED_EDGE('',*,*,#788,.T.); -#1037 = ORIENTED_EDGE('',*,*,#1022,.F.); -#1038 = ORIENTED_EDGE('',*,*,#990,.F.); -#1039 = ORIENTED_EDGE('',*,*,#1040,.F.); -#1040 = EDGE_CURVE('',#789,#991,#1041,.T.); -#1041 = LINE('',#1042,#1043); -#1042 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#1043 = VECTOR('',#1044,1.); -#1044 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#1045 = PLANE('',#1046); -#1046 = AXIS2_PLACEMENT_3D('',#1047,#1048,#1049); -#1047 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#1048 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1049 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487824E-02) - ); -#1050 = ADVANCED_FACE('',(#1051),#1056,.F.); -#1051 = FACE_BOUND('',#1052,.F.); -#1052 = EDGE_LOOP('',(#1053,#1054,#1055)); -#1053 = ORIENTED_EDGE('',*,*,#1040,.T.); -#1054 = ORIENTED_EDGE('',*,*,#1007,.F.); -#1055 = ORIENTED_EDGE('',*,*,#796,.T.); -#1056 = PLANE('',#1057); -#1057 = AXIS2_PLACEMENT_3D('',#1058,#1059,#1060); -#1058 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -49.69378323641)); -#1059 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#1060 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#1061 = ADVANCED_FACE('',(#1062),#1081,.T.); -#1062 = FACE_BOUND('',#1063,.T.); -#1063 = EDGE_LOOP('',(#1064,#1073,#1079,#1080)); -#1064 = ORIENTED_EDGE('',*,*,#1065,.T.); -#1065 = EDGE_CURVE('',#1066,#1066,#1068,.T.); -#1066 = VERTEX_POINT('',#1067); -#1067 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#1068 = CIRCLE('',#1069,4.735522705283); -#1069 = AXIS2_PLACEMENT_3D('',#1070,#1071,#1072); -#1070 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#1071 = DIRECTION('',(-0.,1.,0.)); -#1072 = DIRECTION('',(1.,0.,0.)); -#1073 = ORIENTED_EDGE('',*,*,#1074,.T.); -#1074 = EDGE_CURVE('',#1066,#805,#1075,.T.); -#1075 = LINE('',#1076,#1077); -#1076 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#1077 = VECTOR('',#1078,1.); -#1078 = DIRECTION('',(0.,1.,0.)); -#1079 = ORIENTED_EDGE('',*,*,#804,.F.); -#1080 = ORIENTED_EDGE('',*,*,#1074,.F.); -#1081 = CYLINDRICAL_SURFACE('',#1082,4.735522705283); -#1082 = AXIS2_PLACEMENT_3D('',#1083,#1084,#1085); -#1083 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#1084 = DIRECTION('',(0.,1.,0.)); -#1085 = DIRECTION('',(1.,0.,0.)); -#1086 = ADVANCED_FACE('',(#1087),#1095,.F.); -#1087 = FACE_BOUND('',#1088,.F.); -#1088 = EDGE_LOOP('',(#1089,#1090,#1091,#1092,#1093,#1094)); -#1089 = ORIENTED_EDGE('',*,*,#860,.T.); -#1090 = ORIENTED_EDGE('',*,*,#829,.T.); -#1091 = ORIENTED_EDGE('',*,*,#948,.T.); -#1092 = ORIENTED_EDGE('',*,*,#924,.T.); -#1093 = ORIENTED_EDGE('',*,*,#900,.T.); -#1094 = ORIENTED_EDGE('',*,*,#876,.T.); -#1095 = PLANE('',#1096); -#1096 = AXIS2_PLACEMENT_3D('',#1097,#1098,#1099); -#1097 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1098 = DIRECTION('',(0.,1.,0.)); -#1099 = DIRECTION('',(0.,0.,1.)); -#1100 = ADVANCED_FACE('',(#1101),#1104,.F.); -#1101 = FACE_BOUND('',#1102,.F.); -#1102 = EDGE_LOOP('',(#1103)); -#1103 = ORIENTED_EDGE('',*,*,#965,.T.); -#1104 = PLANE('',#1105); -#1105 = AXIS2_PLACEMENT_3D('',#1106,#1107,#1108); -#1106 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1107 = DIRECTION('',(0.,1.,0.)); -#1108 = DIRECTION('',(0.,0.,1.)); -#1109 = ADVANCED_FACE('',(#1110),#1113,.F.); -#1110 = FACE_BOUND('',#1111,.F.); -#1111 = EDGE_LOOP('',(#1112)); -#1112 = ORIENTED_EDGE('',*,*,#1065,.T.); -#1113 = PLANE('',#1114); -#1114 = AXIS2_PLACEMENT_3D('',#1115,#1116,#1117); -#1115 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1116 = DIRECTION('',(0.,1.,0.)); -#1117 = DIRECTION('',(0.,0.,1.)); -#1118 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1122)) -GLOBAL_UNIT_ASSIGNED_CONTEXT((#1119,#1120,#1121)) REPRESENTATION_CONTEXT -('Context #1','3D Context with UNIT and UNCERTAINTY') ); -#1119 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#1120 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#1121 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#1122 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-05),#1119, - 'distance_accuracy_value','confusion accuracy'); -#1123 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step deleted file mode 100644 index e6575701e4..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.step +++ /dev/null @@ -1,1048 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T11:06:23',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 1', - 'Open CASCADE STEP translator 7.8 1','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#976); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#157,#188,#212,#236,#261,#285,#310,#334,#358, - #383,#407,#432,#456,#480,#504,#528,#545,#675,#706,#730,#754,#778, - #802,#819,#850,#866,#882,#894,#919,#944,#958,#967)); -#17 = ADVANCED_FACE('',(#18),#152,.T.); -#18 = FACE_BOUND('',#19,.T.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62,#70,#79,#87,#96,#104,#112, - #121,#129,#138,#146)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(26.824640127118,20.8572529153,-55.23443461327) - ); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(42.184838000445,20.8572529153,-7.043416644207) - ); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(28.89442018934,20.8572529153,-48.74071565254) - ); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(32.56245481215,20.8572529153,-60.7871552419)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(12.092418778801,20.8572529153,-40.97745458223) - ); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(26.712845130625,20.8572529153,-66.83175546171) - ); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(11.149878706433,20.8572529153,-82.91349687528) - ); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(20.57248334837,20.8572529153,-60.88947335481) - ); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(9.111716439792,20.8572529153,-49.79841511636) - ); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(-20.57248334837,20.8572529153,-60.88947335481) - ); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-12.44623571629,20.8572529153,-60.88947335481) - ); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.T.); -#63 = EDGE_CURVE('',#56,#64,#66,.T.); -#64 = VERTEX_POINT('',#65); -#65 = CARTESIAN_POINT('',(-25.60006917852,20.8572529153,-65.75487614033) - ); -#66 = LINE('',#67,#68); -#67 = CARTESIAN_POINT('',(-32.03294606502,20.8572529153,-71.98023721416) - ); -#68 = VECTOR('',#69,1.); -#69 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#64,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(-27.78972445201,20.8572529153,-65.71897950961) - ); -#74 = CIRCLE('',#75,1.548528137424); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(-26.67694849991,20.8572529153,-64.64210018823) - ); -#77 = DIRECTION('',(0.,-1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = ORIENTED_EDGE('',*,*,#80,.T.); -#80 = EDGE_CURVE('',#72,#81,#83,.T.); -#81 = VERTEX_POINT('',#82); -#82 = CARTESIAN_POINT('',(-29.01580660709,20.8572529153,-64.4520272055) - ); -#83 = LINE('',#84,#85); -#84 = CARTESIAN_POINT('',(-31.36389178357,20.8572529153,-62.02567109858) - ); -#85 = VECTOR('',#86,1.); -#86 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#87 = ORIENTED_EDGE('',*,*,#88,.F.); -#88 = EDGE_CURVE('',#89,#81,#91,.T.); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(-28.89758284854,20.8572529153,-57.24050703685) - ); -#91 = CIRCLE('',#92,5.1); -#92 = AXIS2_PLACEMENT_3D('',#93,#94,#95); -#93 = CARTESIAN_POINT('',(-25.35093464349,20.8572529153,-60.90537900045) - ); -#94 = DIRECTION('',(0.,-1.,0.)); -#95 = DIRECTION('',(1.,0.,0.)); -#96 = ORIENTED_EDGE('',*,*,#97,.T.); -#97 = EDGE_CURVE('',#89,#98,#100,.T.); -#98 = VERTEX_POINT('',#99); -#99 = CARTESIAN_POINT('',(-26.82464012711,20.8572529153,-55.23443461327) - ); -#100 = LINE('',#101,#102); -#101 = CARTESIAN_POINT('',(-35.57003638008,20.8572529153,-63.69771634073 - )); -#102 = VECTOR('',#103,1.); -#103 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#104 = ORIENTED_EDGE('',*,*,#105,.T.); -#105 = EDGE_CURVE('',#98,#106,#108,.T.); -#106 = VERTEX_POINT('',#107); -#107 = CARTESIAN_POINT('',(-41.08376419406,20.8572529153,-10.49792081311 - )); -#108 = LINE('',#109,#110); -#109 = CARTESIAN_POINT('',(-32.53680963915,20.8572529153,-37.31309884227 - )); -#110 = VECTOR('',#111,1.); -#111 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#112 = ORIENTED_EDGE('',*,*,#113,.F.); -#113 = EDGE_CURVE('',#114,#106,#116,.T.); -#114 = VERTEX_POINT('',#115); -#115 = CARTESIAN_POINT('',(-39.62105538679,20.8572529153,-4.479634030555 - )); -#116 = CIRCLE('',#117,5.954044962965); -#117 = AXIS2_PLACEMENT_3D('',#118,#119,#120); -#118 = CARTESIAN_POINT('',(-35.41090981799,20.8572529153,-8.689779599357 - )); -#119 = DIRECTION('',(0.,-1.,0.)); -#120 = DIRECTION('',(1.,0.,0.)); -#121 = ORIENTED_EDGE('',*,*,#122,.T.); -#122 = EDGE_CURVE('',#114,#123,#125,.T.); -#123 = VERTEX_POINT('',#124); -#124 = CARTESIAN_POINT('',(-36.7853207504,20.8572529153,-1.643899394163) - ); -#125 = LINE('',#126,#127); -#126 = CARTESIAN_POINT('',(-56.28754386398,20.8572529153,-21.14612250775 - )); -#127 = VECTOR('',#128,1.); -#128 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#129 = ORIENTED_EDGE('',*,*,#130,.F.); -#130 = EDGE_CURVE('',#131,#123,#133,.T.); -#131 = VERTEX_POINT('',#132); -#132 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153, - 9.999999999998E-02)); -#133 = CIRCLE('',#134,5.954044962965); -#134 = AXIS2_PLACEMENT_3D('',#135,#136,#137); -#135 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,-5.854044962965 - )); -#136 = DIRECTION('',(0.,-1.,0.)); -#137 = DIRECTION('',(1.,0.,0.)); -#138 = ORIENTED_EDGE('',*,*,#139,.T.); -#139 = EDGE_CURVE('',#131,#140,#142,.T.); -#140 = VERTEX_POINT('',#141); -#141 = CARTESIAN_POINT('',(35.041421356237,20.8572529153,0.1)); -#142 = LINE('',#143,#144); -#143 = CARTESIAN_POINT('',(-5.211766712356,20.8572529153,0.1)); -#144 = VECTOR('',#145,1.); -#145 = DIRECTION('',(1.,0.,0.)); -#146 = ORIENTED_EDGE('',*,*,#147,.F.); -#147 = EDGE_CURVE('',#24,#140,#148,.T.); -#148 = LINE('',#149,#150); -#149 = CARTESIAN_POINT('',(32.68311677643,20.8572529153,2.458304579807) - ); -#150 = VECTOR('',#151,1.); -#151 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#152 = PLANE('',#153); -#153 = AXIS2_PLACEMENT_3D('',#154,#155,#156); -#154 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153,-70.97315781796 - )); -#155 = DIRECTION('',(0.,1.,0.)); -#156 = DIRECTION('',(0.,0.,1.)); -#157 = ADVANCED_FACE('',(#158),#183,.F.); -#158 = FACE_BOUND('',#159,.F.); -#159 = EDGE_LOOP('',(#160,#170,#176,#177)); -#160 = ORIENTED_EDGE('',*,*,#161,.T.); -#161 = EDGE_CURVE('',#162,#164,#166,.T.); -#162 = VERTEX_POINT('',#163); -#163 = CARTESIAN_POINT('',(26.824640127118,3.2,-55.23443461327)); -#164 = VERTEX_POINT('',#165); -#165 = CARTESIAN_POINT('',(42.184838000445,3.2,-7.043416644207)); -#166 = LINE('',#167,#168); -#167 = CARTESIAN_POINT('',(36.45312509682,3.2,-25.02606776693)); -#168 = VECTOR('',#169,1.); -#169 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#170 = ORIENTED_EDGE('',*,*,#171,.T.); -#171 = EDGE_CURVE('',#164,#24,#172,.T.); -#172 = LINE('',#173,#174); -#173 = CARTESIAN_POINT('',(42.184838000445,-5.,-7.043416644207)); -#174 = VECTOR('',#175,1.); -#175 = DIRECTION('',(0.,1.,0.)); -#176 = ORIENTED_EDGE('',*,*,#21,.F.); -#177 = ORIENTED_EDGE('',*,*,#178,.F.); -#178 = EDGE_CURVE('',#162,#22,#179,.T.); -#179 = LINE('',#180,#181); -#180 = CARTESIAN_POINT('',(26.824640127118,-5.,-55.23443461327)); -#181 = VECTOR('',#182,1.); -#182 = DIRECTION('',(0.,1.,0.)); -#183 = PLANE('',#184); -#184 = AXIS2_PLACEMENT_3D('',#185,#186,#187); -#185 = CARTESIAN_POINT('',(42.184838000445,-5.,-7.043416644207)); -#186 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#187 = DIRECTION('',(-0.30368282823,0.,-0.952773183837)); -#188 = ADVANCED_FACE('',(#189),#207,.F.); -#189 = FACE_BOUND('',#190,.F.); -#190 = EDGE_LOOP('',(#191,#199,#205,#206)); -#191 = ORIENTED_EDGE('',*,*,#192,.T.); -#192 = EDGE_CURVE('',#164,#193,#195,.T.); -#193 = VERTEX_POINT('',#194); -#194 = CARTESIAN_POINT('',(35.041421356237,3.2,0.1)); -#195 = LINE('',#196,#197); -#196 = CARTESIAN_POINT('',(34.743124284224,3.2,0.398297072013)); -#197 = VECTOR('',#198,1.); -#198 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#199 = ORIENTED_EDGE('',*,*,#200,.T.); -#200 = EDGE_CURVE('',#193,#140,#201,.T.); -#201 = LINE('',#202,#203); -#202 = CARTESIAN_POINT('',(35.041421356237,-5.,0.1)); -#203 = VECTOR('',#204,1.); -#204 = DIRECTION('',(0.,1.,0.)); -#205 = ORIENTED_EDGE('',*,*,#147,.F.); -#206 = ORIENTED_EDGE('',*,*,#171,.F.); -#207 = PLANE('',#208); -#208 = AXIS2_PLACEMENT_3D('',#209,#210,#211); -#209 = CARTESIAN_POINT('',(35.041421356237,-5.,9.999999999998E-02)); -#210 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#211 = DIRECTION('',(0.707106781187,0.,-0.707106781187)); -#212 = ADVANCED_FACE('',(#213),#231,.T.); -#213 = FACE_BOUND('',#214,.T.); -#214 = EDGE_LOOP('',(#215,#223,#224,#225)); -#215 = ORIENTED_EDGE('',*,*,#216,.T.); -#216 = EDGE_CURVE('',#217,#193,#219,.T.); -#217 = VERTEX_POINT('',#218); -#218 = CARTESIAN_POINT('',(-32.57517518159,3.2,9.999999999998E-02)); -#219 = LINE('',#220,#221); -#220 = CARTESIAN_POINT('',(17.722238935846,3.2,0.1)); -#221 = VECTOR('',#222,1.); -#222 = DIRECTION('',(1.,0.,0.)); -#223 = ORIENTED_EDGE('',*,*,#200,.T.); -#224 = ORIENTED_EDGE('',*,*,#139,.F.); -#225 = ORIENTED_EDGE('',*,*,#226,.F.); -#226 = EDGE_CURVE('',#217,#131,#227,.T.); -#227 = LINE('',#228,#229); -#228 = CARTESIAN_POINT('',(-32.57517518159,-5.,9.999999999998E-02)); -#229 = VECTOR('',#230,1.); -#230 = DIRECTION('',(0.,1.,0.)); -#231 = PLANE('',#232); -#232 = AXIS2_PLACEMENT_3D('',#233,#234,#235); -#233 = CARTESIAN_POINT('',(35.041421356237,-5.,0.1)); -#234 = DIRECTION('',(0.,0.,1.)); -#235 = DIRECTION('',(-1.,0.,0.)); -#236 = ADVANCED_FACE('',(#237),#256,.T.); -#237 = FACE_BOUND('',#238,.F.); -#238 = EDGE_LOOP('',(#239,#248,#254,#255)); -#239 = ORIENTED_EDGE('',*,*,#240,.T.); -#240 = EDGE_CURVE('',#217,#241,#243,.T.); -#241 = VERTEX_POINT('',#242); -#242 = CARTESIAN_POINT('',(-36.7853207504,3.2,-1.643899394163)); -#243 = CIRCLE('',#244,5.954044962965); -#244 = AXIS2_PLACEMENT_3D('',#245,#246,#247); -#245 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#246 = DIRECTION('',(0.,-1.,0.)); -#247 = DIRECTION('',(1.,0.,0.)); -#248 = ORIENTED_EDGE('',*,*,#249,.T.); -#249 = EDGE_CURVE('',#241,#123,#250,.T.); -#250 = LINE('',#251,#252); -#251 = CARTESIAN_POINT('',(-36.7853207504,-5.,-1.643899394163)); -#252 = VECTOR('',#253,1.); -#253 = DIRECTION('',(0.,1.,0.)); -#254 = ORIENTED_EDGE('',*,*,#130,.F.); -#255 = ORIENTED_EDGE('',*,*,#226,.F.); -#256 = CYLINDRICAL_SURFACE('',#257,5.954044962965); -#257 = AXIS2_PLACEMENT_3D('',#258,#259,#260); -#258 = CARTESIAN_POINT('',(-32.57517518159,-5.,-5.854044962965)); -#259 = DIRECTION('',(0.,-1.,0.)); -#260 = DIRECTION('',(1.,0.,0.)); -#261 = ADVANCED_FACE('',(#262),#280,.T.); -#262 = FACE_BOUND('',#263,.T.); -#263 = EDGE_LOOP('',(#264,#272,#273,#274)); -#264 = ORIENTED_EDGE('',*,*,#265,.T.); -#265 = EDGE_CURVE('',#266,#241,#268,.T.); -#266 = VERTEX_POINT('',#267); -#267 = CARTESIAN_POINT('',(-39.62105538679,3.2,-4.479634030555)); -#268 = LINE('',#269,#270); -#269 = CARTESIAN_POINT('',(-35.41354572357,3.2,-0.272124367341)); -#270 = VECTOR('',#271,1.); -#271 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#272 = ORIENTED_EDGE('',*,*,#249,.T.); -#273 = ORIENTED_EDGE('',*,*,#122,.F.); -#274 = ORIENTED_EDGE('',*,*,#275,.F.); -#275 = EDGE_CURVE('',#266,#114,#276,.T.); -#276 = LINE('',#277,#278); -#277 = CARTESIAN_POINT('',(-39.62105538679,-5.,-4.479634030555)); -#278 = VECTOR('',#279,1.); -#279 = DIRECTION('',(0.,1.,0.)); -#280 = PLANE('',#281); -#281 = AXIS2_PLACEMENT_3D('',#282,#283,#284); -#282 = CARTESIAN_POINT('',(-36.7853207504,-5.,-1.643899394163)); -#283 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#284 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#285 = ADVANCED_FACE('',(#286),#305,.T.); -#286 = FACE_BOUND('',#287,.F.); -#287 = EDGE_LOOP('',(#288,#297,#303,#304)); -#288 = ORIENTED_EDGE('',*,*,#289,.T.); -#289 = EDGE_CURVE('',#266,#290,#292,.T.); -#290 = VERTEX_POINT('',#291); -#291 = CARTESIAN_POINT('',(-41.08376419406,3.2,-10.49792081311)); -#292 = CIRCLE('',#293,5.954044962965); -#293 = AXIS2_PLACEMENT_3D('',#294,#295,#296); -#294 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#295 = DIRECTION('',(0.,-1.,0.)); -#296 = DIRECTION('',(1.,0.,0.)); -#297 = ORIENTED_EDGE('',*,*,#298,.T.); -#298 = EDGE_CURVE('',#290,#106,#299,.T.); -#299 = LINE('',#300,#301); -#300 = CARTESIAN_POINT('',(-41.08376419406,-5.,-10.49792081311)); -#301 = VECTOR('',#302,1.); -#302 = DIRECTION('',(0.,1.,0.)); -#303 = ORIENTED_EDGE('',*,*,#113,.F.); -#304 = ORIENTED_EDGE('',*,*,#275,.F.); -#305 = CYLINDRICAL_SURFACE('',#306,5.954044962965); -#306 = AXIS2_PLACEMENT_3D('',#307,#308,#309); -#307 = CARTESIAN_POINT('',(-35.41090981799,-5.,-8.689779599357)); -#308 = DIRECTION('',(0.,-1.,0.)); -#309 = DIRECTION('',(1.,0.,0.)); -#310 = ADVANCED_FACE('',(#311),#329,.T.); -#311 = FACE_BOUND('',#312,.T.); -#312 = EDGE_LOOP('',(#313,#321,#322,#323)); -#313 = ORIENTED_EDGE('',*,*,#314,.T.); -#314 = EDGE_CURVE('',#315,#290,#317,.T.); -#315 = VERTEX_POINT('',#316); -#316 = CARTESIAN_POINT('',(-26.82464012711,3.2,-55.23443461327)); -#317 = LINE('',#318,#319); -#318 = CARTESIAN_POINT('',(-35.86541700774,3.2,-26.86994056823)); -#319 = VECTOR('',#320,1.); -#320 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#321 = ORIENTED_EDGE('',*,*,#298,.T.); -#322 = ORIENTED_EDGE('',*,*,#105,.F.); -#323 = ORIENTED_EDGE('',*,*,#324,.F.); -#324 = EDGE_CURVE('',#315,#98,#325,.T.); -#325 = LINE('',#326,#327); -#326 = CARTESIAN_POINT('',(-26.82464012711,-5.,-55.23443461327)); -#327 = VECTOR('',#328,1.); -#328 = DIRECTION('',(0.,1.,0.)); -#329 = PLANE('',#330); -#330 = AXIS2_PLACEMENT_3D('',#331,#332,#333); -#331 = CARTESIAN_POINT('',(-41.08376419406,-5.,-10.49792081311)); -#332 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#333 = DIRECTION('',(0.30368282823,0.,-0.952773183837)); -#334 = ADVANCED_FACE('',(#335),#353,.T.); -#335 = FACE_BOUND('',#336,.T.); -#336 = EDGE_LOOP('',(#337,#345,#346,#347)); -#337 = ORIENTED_EDGE('',*,*,#338,.T.); -#338 = EDGE_CURVE('',#339,#315,#341,.T.); -#339 = VERTEX_POINT('',#340); -#340 = CARTESIAN_POINT('',(-28.89758284854,3.2,-57.24050703685)); -#341 = LINE('',#342,#343); -#342 = CARTESIAN_POINT('',(-14.32522020853,3.2,-43.13822889076)); -#343 = VECTOR('',#344,1.); -#344 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#345 = ORIENTED_EDGE('',*,*,#324,.T.); -#346 = ORIENTED_EDGE('',*,*,#97,.F.); -#347 = ORIENTED_EDGE('',*,*,#348,.F.); -#348 = EDGE_CURVE('',#339,#89,#349,.T.); -#349 = LINE('',#350,#351); -#350 = CARTESIAN_POINT('',(-28.89758284854,-5.,-57.24050703685)); -#351 = VECTOR('',#352,1.); -#352 = DIRECTION('',(0.,1.,0.)); -#353 = PLANE('',#354); -#354 = AXIS2_PLACEMENT_3D('',#355,#356,#357); -#355 = CARTESIAN_POINT('',(-26.82464012711,-5.,-55.23443461327)); -#356 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#357 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#358 = ADVANCED_FACE('',(#359),#378,.T.); -#359 = FACE_BOUND('',#360,.F.); -#360 = EDGE_LOOP('',(#361,#370,#376,#377)); -#361 = ORIENTED_EDGE('',*,*,#362,.T.); -#362 = EDGE_CURVE('',#339,#363,#365,.T.); -#363 = VERTEX_POINT('',#364); -#364 = CARTESIAN_POINT('',(-29.01580660709,3.2,-64.4520272055)); -#365 = CIRCLE('',#366,5.1); -#366 = AXIS2_PLACEMENT_3D('',#367,#368,#369); -#367 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#368 = DIRECTION('',(0.,-1.,0.)); -#369 = DIRECTION('',(1.,0.,0.)); -#370 = ORIENTED_EDGE('',*,*,#371,.T.); -#371 = EDGE_CURVE('',#363,#81,#372,.T.); -#372 = LINE('',#373,#374); -#373 = CARTESIAN_POINT('',(-29.01580660709,-5.,-64.4520272055)); -#374 = VECTOR('',#375,1.); -#375 = DIRECTION('',(0.,1.,0.)); -#376 = ORIENTED_EDGE('',*,*,#88,.F.); -#377 = ORIENTED_EDGE('',*,*,#348,.F.); -#378 = CYLINDRICAL_SURFACE('',#379,5.1); -#379 = AXIS2_PLACEMENT_3D('',#380,#381,#382); -#380 = CARTESIAN_POINT('',(-25.35093464349,-5.,-60.90537900045)); -#381 = DIRECTION('',(0.,-1.,0.)); -#382 = DIRECTION('',(1.,0.,0.)); -#383 = ADVANCED_FACE('',(#384),#402,.T.); -#384 = FACE_BOUND('',#385,.T.); -#385 = EDGE_LOOP('',(#386,#394,#395,#396)); -#386 = ORIENTED_EDGE('',*,*,#387,.T.); -#387 = EDGE_CURVE('',#388,#363,#390,.T.); -#388 = VERTEX_POINT('',#389); -#389 = CARTESIAN_POINT('',(-27.78972445201,3.2,-65.71897950961)); -#390 = LINE('',#391,#392); -#391 = CARTESIAN_POINT('',(-29.67470230692,3.2,-63.77116791594)); -#392 = VECTOR('',#393,1.); -#393 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#394 = ORIENTED_EDGE('',*,*,#371,.T.); -#395 = ORIENTED_EDGE('',*,*,#80,.F.); -#396 = ORIENTED_EDGE('',*,*,#397,.F.); -#397 = EDGE_CURVE('',#388,#72,#398,.T.); -#398 = LINE('',#399,#400); -#399 = CARTESIAN_POINT('',(-27.78972445201,-5.,-65.71897950961)); -#400 = VECTOR('',#401,1.); -#401 = DIRECTION('',(0.,1.,0.)); -#402 = PLANE('',#403); -#403 = AXIS2_PLACEMENT_3D('',#404,#405,#406); -#404 = CARTESIAN_POINT('',(-29.01580660709,-5.,-64.4520272055)); -#405 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#406 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#407 = ADVANCED_FACE('',(#408),#427,.T.); -#408 = FACE_BOUND('',#409,.F.); -#409 = EDGE_LOOP('',(#410,#419,#425,#426)); -#410 = ORIENTED_EDGE('',*,*,#411,.T.); -#411 = EDGE_CURVE('',#388,#412,#414,.T.); -#412 = VERTEX_POINT('',#413); -#413 = CARTESIAN_POINT('',(-25.60006917852,3.2,-65.75487614033)); -#414 = CIRCLE('',#415,1.548528137424); -#415 = AXIS2_PLACEMENT_3D('',#416,#417,#418); -#416 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#417 = DIRECTION('',(0.,-1.,0.)); -#418 = DIRECTION('',(1.,0.,0.)); -#419 = ORIENTED_EDGE('',*,*,#420,.T.); -#420 = EDGE_CURVE('',#412,#64,#421,.T.); -#421 = LINE('',#422,#423); -#422 = CARTESIAN_POINT('',(-25.60006917852,-5.,-65.75487614033)); -#423 = VECTOR('',#424,1.); -#424 = DIRECTION('',(0.,1.,0.)); -#425 = ORIENTED_EDGE('',*,*,#71,.F.); -#426 = ORIENTED_EDGE('',*,*,#397,.F.); -#427 = CYLINDRICAL_SURFACE('',#428,1.548528137424); -#428 = AXIS2_PLACEMENT_3D('',#429,#430,#431); -#429 = CARTESIAN_POINT('',(-26.67694849991,-5.,-64.64210018823)); -#430 = DIRECTION('',(0.,-1.,0.)); -#431 = DIRECTION('',(1.,0.,0.)); -#432 = ADVANCED_FACE('',(#433),#451,.T.); -#433 = FACE_BOUND('',#434,.T.); -#434 = EDGE_LOOP('',(#435,#443,#444,#445)); -#435 = ORIENTED_EDGE('',*,*,#436,.T.); -#436 = EDGE_CURVE('',#437,#412,#439,.T.); -#437 = VERTEX_POINT('',#438); -#438 = CARTESIAN_POINT('',(-20.57248334837,3.2,-60.88947335481)); -#439 = LINE('',#440,#441); -#440 = CARTESIAN_POINT('',(-10.78812989347,3.2,-51.42074976419)); -#441 = VECTOR('',#442,1.); -#442 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#443 = ORIENTED_EDGE('',*,*,#420,.T.); -#444 = ORIENTED_EDGE('',*,*,#63,.F.); -#445 = ORIENTED_EDGE('',*,*,#446,.F.); -#446 = EDGE_CURVE('',#437,#56,#447,.T.); -#447 = LINE('',#448,#449); -#448 = CARTESIAN_POINT('',(-20.57248334837,-5.,-60.88947335481)); -#449 = VECTOR('',#450,1.); -#450 = DIRECTION('',(0.,1.,0.)); -#451 = PLANE('',#452); -#452 = AXIS2_PLACEMENT_3D('',#453,#454,#455); -#453 = CARTESIAN_POINT('',(-25.60006917852,-5.,-65.75487614033)); -#454 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#455 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#456 = ADVANCED_FACE('',(#457),#475,.F.); -#457 = FACE_BOUND('',#458,.F.); -#458 = EDGE_LOOP('',(#459,#467,#473,#474)); -#459 = ORIENTED_EDGE('',*,*,#460,.T.); -#460 = EDGE_CURVE('',#437,#461,#463,.T.); -#461 = VERTEX_POINT('',#462); -#462 = CARTESIAN_POINT('',(20.57248334837,3.2,-60.88947335481)); -#463 = LINE('',#464,#465); -#464 = CARTESIAN_POINT('',(10.487769931912,3.2,-60.88947335481)); -#465 = VECTOR('',#466,1.); -#466 = DIRECTION('',(1.,0.,0.)); -#467 = ORIENTED_EDGE('',*,*,#468,.T.); -#468 = EDGE_CURVE('',#461,#48,#469,.T.); -#469 = LINE('',#470,#471); -#470 = CARTESIAN_POINT('',(20.57248334837,-5.,-60.88947335481)); -#471 = VECTOR('',#472,1.); -#472 = DIRECTION('',(0.,1.,0.)); -#473 = ORIENTED_EDGE('',*,*,#55,.F.); -#474 = ORIENTED_EDGE('',*,*,#446,.F.); -#475 = PLANE('',#476); -#476 = AXIS2_PLACEMENT_3D('',#477,#478,#479); -#477 = CARTESIAN_POINT('',(20.57248334837,-5.,-60.88947335481)); -#478 = DIRECTION('',(0.,0.,1.)); -#479 = DIRECTION('',(-1.,0.,0.)); -#480 = ADVANCED_FACE('',(#481),#499,.F.); -#481 = FACE_BOUND('',#482,.F.); -#482 = EDGE_LOOP('',(#483,#491,#497,#498)); -#483 = ORIENTED_EDGE('',*,*,#484,.T.); -#484 = EDGE_CURVE('',#461,#485,#487,.T.); -#485 = VERTEX_POINT('',#486); -#486 = CARTESIAN_POINT('',(26.712845130625,3.2,-66.83175546171)); -#487 = LINE('',#488,#489); -#488 = CARTESIAN_POINT('',(11.552651954056,3.2,-52.16060938843)); -#489 = VECTOR('',#490,1.); -#490 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#491 = ORIENTED_EDGE('',*,*,#492,.T.); -#492 = EDGE_CURVE('',#485,#40,#493,.T.); -#493 = LINE('',#494,#495); -#494 = CARTESIAN_POINT('',(26.712845130625,-5.,-66.83175546171)); -#495 = VECTOR('',#496,1.); -#496 = DIRECTION('',(0.,1.,0.)); -#497 = ORIENTED_EDGE('',*,*,#47,.F.); -#498 = ORIENTED_EDGE('',*,*,#468,.F.); -#499 = PLANE('',#500); -#500 = AXIS2_PLACEMENT_3D('',#501,#502,#503); -#501 = CARTESIAN_POINT('',(26.712845130625,-5.,-66.83175546171)); -#502 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#503 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#504 = ADVANCED_FACE('',(#505),#523,.F.); -#505 = FACE_BOUND('',#506,.F.); -#506 = EDGE_LOOP('',(#507,#515,#521,#522)); -#507 = ORIENTED_EDGE('',*,*,#508,.T.); -#508 = EDGE_CURVE('',#485,#509,#511,.T.); -#509 = VERTEX_POINT('',#510); -#510 = CARTESIAN_POINT('',(32.56245481215,3.2,-60.7871552419)); -#511 = LINE('',#512,#513); -#512 = CARTESIAN_POINT('',(31.642948840372,3.2,-61.73731197059)); -#513 = VECTOR('',#514,1.); -#514 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#515 = ORIENTED_EDGE('',*,*,#516,.T.); -#516 = EDGE_CURVE('',#509,#32,#517,.T.); -#517 = LINE('',#518,#519); -#518 = CARTESIAN_POINT('',(32.56245481215,-5.,-60.7871552419)); -#519 = VECTOR('',#520,1.); -#520 = DIRECTION('',(0.,1.,0.)); -#521 = ORIENTED_EDGE('',*,*,#39,.F.); -#522 = ORIENTED_EDGE('',*,*,#492,.F.); -#523 = PLANE('',#524); -#524 = AXIS2_PLACEMENT_3D('',#525,#526,#527); -#525 = CARTESIAN_POINT('',(32.56245481215,-5.,-60.7871552419)); -#526 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#527 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#528 = ADVANCED_FACE('',(#529),#540,.F.); -#529 = FACE_BOUND('',#530,.F.); -#530 = EDGE_LOOP('',(#531,#537,#538,#539)); -#531 = ORIENTED_EDGE('',*,*,#532,.T.); -#532 = EDGE_CURVE('',#509,#162,#533,.T.); -#533 = LINE('',#534,#535); -#534 = CARTESIAN_POINT('',(14.533354293065,3.2,-43.3396488543)); -#535 = VECTOR('',#536,1.); -#536 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#537 = ORIENTED_EDGE('',*,*,#178,.T.); -#538 = ORIENTED_EDGE('',*,*,#31,.F.); -#539 = ORIENTED_EDGE('',*,*,#516,.F.); -#540 = PLANE('',#541); -#541 = AXIS2_PLACEMENT_3D('',#542,#543,#544); -#542 = CARTESIAN_POINT('',(26.824640127118,-5.,-55.23443461327)); -#543 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#544 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#545 = ADVANCED_FACE('',(#546,#564,#614,#648,#659),#670,.F.); -#546 = FACE_BOUND('',#547,.F.); -#547 = EDGE_LOOP('',(#548,#549,#550,#551,#552,#553,#554,#555,#556,#557, - #558,#559,#560,#561,#562,#563)); -#548 = ORIENTED_EDGE('',*,*,#161,.F.); -#549 = ORIENTED_EDGE('',*,*,#532,.F.); -#550 = ORIENTED_EDGE('',*,*,#508,.F.); -#551 = ORIENTED_EDGE('',*,*,#484,.F.); -#552 = ORIENTED_EDGE('',*,*,#460,.F.); -#553 = ORIENTED_EDGE('',*,*,#436,.T.); -#554 = ORIENTED_EDGE('',*,*,#411,.F.); -#555 = ORIENTED_EDGE('',*,*,#387,.T.); -#556 = ORIENTED_EDGE('',*,*,#362,.F.); -#557 = ORIENTED_EDGE('',*,*,#338,.T.); -#558 = ORIENTED_EDGE('',*,*,#314,.T.); -#559 = ORIENTED_EDGE('',*,*,#289,.F.); -#560 = ORIENTED_EDGE('',*,*,#265,.T.); -#561 = ORIENTED_EDGE('',*,*,#240,.F.); -#562 = ORIENTED_EDGE('',*,*,#216,.T.); -#563 = ORIENTED_EDGE('',*,*,#192,.F.); -#564 = FACE_BOUND('',#565,.F.); -#565 = EDGE_LOOP('',(#566,#576,#584,#592,#600,#608)); -#566 = ORIENTED_EDGE('',*,*,#567,.F.); -#567 = EDGE_CURVE('',#568,#570,#572,.T.); -#568 = VERTEX_POINT('',#569); -#569 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#570 = VERTEX_POINT('',#571); -#571 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#572 = LINE('',#573,#574); -#573 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#574 = VECTOR('',#575,1.); -#575 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#576 = ORIENTED_EDGE('',*,*,#577,.F.); -#577 = EDGE_CURVE('',#578,#568,#580,.T.); -#578 = VERTEX_POINT('',#579); -#579 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#580 = LINE('',#581,#582); -#581 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#582 = VECTOR('',#583,1.); -#583 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#584 = ORIENTED_EDGE('',*,*,#585,.F.); -#585 = EDGE_CURVE('',#586,#578,#588,.T.); -#586 = VERTEX_POINT('',#587); -#587 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#588 = LINE('',#589,#590); -#589 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#590 = VECTOR('',#591,1.); -#591 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#592 = ORIENTED_EDGE('',*,*,#593,.F.); -#593 = EDGE_CURVE('',#594,#586,#596,.T.); -#594 = VERTEX_POINT('',#595); -#595 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#596 = LINE('',#597,#598); -#597 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#598 = VECTOR('',#599,1.); -#599 = DIRECTION('',(1.,0.,0.)); -#600 = ORIENTED_EDGE('',*,*,#601,.F.); -#601 = EDGE_CURVE('',#602,#594,#604,.T.); -#602 = VERTEX_POINT('',#603); -#603 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(0.,0.,1.)); -#608 = ORIENTED_EDGE('',*,*,#609,.F.); -#609 = EDGE_CURVE('',#570,#602,#610,.T.); -#610 = LINE('',#611,#612); -#611 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#612 = VECTOR('',#613,1.); -#613 = DIRECTION('',(-1.,0.,0.)); -#614 = FACE_BOUND('',#615,.F.); -#615 = EDGE_LOOP('',(#616,#626,#634,#642)); -#616 = ORIENTED_EDGE('',*,*,#617,.F.); -#617 = EDGE_CURVE('',#618,#620,#622,.T.); -#618 = VERTEX_POINT('',#619); -#619 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#620 = VERTEX_POINT('',#621); -#621 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#622 = LINE('',#623,#624); -#623 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#624 = VECTOR('',#625,1.); -#625 = DIRECTION('',(-8.501532861638E-02,0.,-0.996379643459)); -#626 = ORIENTED_EDGE('',*,*,#627,.F.); -#627 = EDGE_CURVE('',#628,#618,#630,.T.); -#628 = VERTEX_POINT('',#629); -#629 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#630 = LINE('',#631,#632); -#631 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#632 = VECTOR('',#633,1.); -#633 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#634 = ORIENTED_EDGE('',*,*,#635,.F.); -#635 = EDGE_CURVE('',#636,#628,#638,.T.); -#636 = VERTEX_POINT('',#637); -#637 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#638 = LINE('',#639,#640); -#639 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#640 = VECTOR('',#641,1.); -#641 = DIRECTION('',(-8.501532861638E-02,0.,0.996379643459)); -#642 = ORIENTED_EDGE('',*,*,#643,.F.); -#643 = EDGE_CURVE('',#620,#636,#644,.T.); -#644 = LINE('',#645,#646); -#645 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#646 = VECTOR('',#647,1.); -#647 = DIRECTION('',(-1.,0.,0.)); -#648 = FACE_BOUND('',#649,.F.); -#649 = EDGE_LOOP('',(#650)); -#650 = ORIENTED_EDGE('',*,*,#651,.F.); -#651 = EDGE_CURVE('',#652,#652,#654,.T.); -#652 = VERTEX_POINT('',#653); -#653 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#654 = CIRCLE('',#655,4.735522705283); -#655 = AXIS2_PLACEMENT_3D('',#656,#657,#658); -#656 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#657 = DIRECTION('',(-0.,1.,0.)); -#658 = DIRECTION('',(1.,0.,0.)); -#659 = FACE_BOUND('',#660,.F.); -#660 = EDGE_LOOP('',(#661)); -#661 = ORIENTED_EDGE('',*,*,#662,.F.); -#662 = EDGE_CURVE('',#663,#663,#665,.T.); -#663 = VERTEX_POINT('',#664); -#664 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#665 = CIRCLE('',#666,4.735522705283); -#666 = AXIS2_PLACEMENT_3D('',#667,#668,#669); -#667 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#668 = DIRECTION('',(-0.,1.,0.)); -#669 = DIRECTION('',(1.,0.,0.)); -#670 = PLANE('',#671); -#671 = AXIS2_PLACEMENT_3D('',#672,#673,#674); -#672 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#673 = DIRECTION('',(0.,1.,0.)); -#674 = DIRECTION('',(1.,0.,0.)); -#675 = ADVANCED_FACE('',(#676),#701,.T.); -#676 = FACE_BOUND('',#677,.T.); -#677 = EDGE_LOOP('',(#678,#686,#694,#700)); -#678 = ORIENTED_EDGE('',*,*,#679,.F.); -#679 = EDGE_CURVE('',#680,#568,#682,.T.); -#680 = VERTEX_POINT('',#681); -#681 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#682 = LINE('',#683,#684); -#683 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#684 = VECTOR('',#685,1.); -#685 = DIRECTION('',(0.,1.,0.)); -#686 = ORIENTED_EDGE('',*,*,#687,.T.); -#687 = EDGE_CURVE('',#680,#688,#690,.T.); -#688 = VERTEX_POINT('',#689); -#689 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#690 = LINE('',#691,#692); -#691 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#692 = VECTOR('',#693,1.); -#693 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#694 = ORIENTED_EDGE('',*,*,#695,.T.); -#695 = EDGE_CURVE('',#688,#570,#696,.T.); -#696 = LINE('',#697,#698); -#697 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#698 = VECTOR('',#699,1.); -#699 = DIRECTION('',(0.,1.,0.)); -#700 = ORIENTED_EDGE('',*,*,#567,.F.); -#701 = PLANE('',#702); -#702 = AXIS2_PLACEMENT_3D('',#703,#704,#705); -#703 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#704 = DIRECTION('',(-2.19152081707E-03,0.,-0.999997598615)); -#705 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#706 = ADVANCED_FACE('',(#707),#725,.T.); -#707 = FACE_BOUND('',#708,.T.); -#708 = EDGE_LOOP('',(#709,#717,#723,#724)); -#709 = ORIENTED_EDGE('',*,*,#710,.F.); -#710 = EDGE_CURVE('',#711,#578,#713,.T.); -#711 = VERTEX_POINT('',#712); -#712 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#713 = LINE('',#714,#715); -#714 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#715 = VECTOR('',#716,1.); -#716 = DIRECTION('',(0.,1.,0.)); -#717 = ORIENTED_EDGE('',*,*,#718,.T.); -#718 = EDGE_CURVE('',#711,#680,#719,.T.); -#719 = LINE('',#720,#721); -#720 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#721 = VECTOR('',#722,1.); -#722 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#723 = ORIENTED_EDGE('',*,*,#679,.T.); -#724 = ORIENTED_EDGE('',*,*,#577,.F.); -#725 = PLANE('',#726); -#726 = AXIS2_PLACEMENT_3D('',#727,#728,#729); -#727 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#728 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#729 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#730 = ADVANCED_FACE('',(#731),#749,.T.); -#731 = FACE_BOUND('',#732,.T.); -#732 = EDGE_LOOP('',(#733,#741,#747,#748)); -#733 = ORIENTED_EDGE('',*,*,#734,.T.); -#734 = EDGE_CURVE('',#688,#735,#737,.T.); -#735 = VERTEX_POINT('',#736); -#736 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#737 = LINE('',#738,#739); -#738 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#739 = VECTOR('',#740,1.); -#740 = DIRECTION('',(-1.,0.,0.)); -#741 = ORIENTED_EDGE('',*,*,#742,.T.); -#742 = EDGE_CURVE('',#735,#602,#743,.T.); -#743 = LINE('',#744,#745); -#744 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#745 = VECTOR('',#746,1.); -#746 = DIRECTION('',(0.,1.,0.)); -#747 = ORIENTED_EDGE('',*,*,#609,.F.); -#748 = ORIENTED_EDGE('',*,*,#695,.F.); -#749 = PLANE('',#750); -#750 = AXIS2_PLACEMENT_3D('',#751,#752,#753); -#751 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#752 = DIRECTION('',(0.,0.,-1.)); -#753 = DIRECTION('',(0.,1.,0.)); -#754 = ADVANCED_FACE('',(#755),#773,.T.); -#755 = FACE_BOUND('',#756,.T.); -#756 = EDGE_LOOP('',(#757,#765,#766,#767)); -#757 = ORIENTED_EDGE('',*,*,#758,.T.); -#758 = EDGE_CURVE('',#759,#711,#761,.T.); -#759 = VERTEX_POINT('',#760); -#760 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#761 = LINE('',#762,#763); -#762 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#763 = VECTOR('',#764,1.); -#764 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#765 = ORIENTED_EDGE('',*,*,#710,.T.); -#766 = ORIENTED_EDGE('',*,*,#585,.F.); -#767 = ORIENTED_EDGE('',*,*,#768,.F.); -#768 = EDGE_CURVE('',#759,#586,#769,.T.); -#769 = LINE('',#770,#771); -#770 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#771 = VECTOR('',#772,1.); -#772 = DIRECTION('',(0.,1.,0.)); -#773 = PLANE('',#774); -#774 = AXIS2_PLACEMENT_3D('',#775,#776,#777); -#775 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#776 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#777 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#778 = ADVANCED_FACE('',(#779),#797,.T.); -#779 = FACE_BOUND('',#780,.T.); -#780 = EDGE_LOOP('',(#781,#789,#795,#796)); -#781 = ORIENTED_EDGE('',*,*,#782,.T.); -#782 = EDGE_CURVE('',#735,#783,#785,.T.); -#783 = VERTEX_POINT('',#784); -#784 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#785 = LINE('',#786,#787); -#786 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#787 = VECTOR('',#788,1.); -#788 = DIRECTION('',(0.,0.,1.)); -#789 = ORIENTED_EDGE('',*,*,#790,.T.); -#790 = EDGE_CURVE('',#783,#594,#791,.T.); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(0.,1.,0.)); -#795 = ORIENTED_EDGE('',*,*,#601,.F.); -#796 = ORIENTED_EDGE('',*,*,#742,.F.); -#797 = PLANE('',#798); -#798 = AXIS2_PLACEMENT_3D('',#799,#800,#801); -#799 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#800 = DIRECTION('',(-1.,0.,0.)); -#801 = DIRECTION('',(0.,1.,0.)); -#802 = ADVANCED_FACE('',(#803),#814,.T.); -#803 = FACE_BOUND('',#804,.T.); -#804 = EDGE_LOOP('',(#805,#811,#812,#813)); -#805 = ORIENTED_EDGE('',*,*,#806,.T.); -#806 = EDGE_CURVE('',#783,#759,#807,.T.); -#807 = LINE('',#808,#809); -#808 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#809 = VECTOR('',#810,1.); -#810 = DIRECTION('',(1.,0.,0.)); -#811 = ORIENTED_EDGE('',*,*,#768,.T.); -#812 = ORIENTED_EDGE('',*,*,#593,.F.); -#813 = ORIENTED_EDGE('',*,*,#790,.F.); -#814 = PLANE('',#815); -#815 = AXIS2_PLACEMENT_3D('',#816,#817,#818); -#816 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#817 = DIRECTION('',(0.,0.,1.)); -#818 = DIRECTION('',(0.,-1.,0.)); -#819 = ADVANCED_FACE('',(#820),#845,.F.); -#820 = FACE_BOUND('',#821,.F.); -#821 = EDGE_LOOP('',(#822,#832,#838,#839)); -#822 = ORIENTED_EDGE('',*,*,#823,.T.); -#823 = EDGE_CURVE('',#824,#826,#828,.T.); -#824 = VERTEX_POINT('',#825); -#825 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#826 = VERTEX_POINT('',#827); -#827 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#828 = LINE('',#829,#830); -#829 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#830 = VECTOR('',#831,1.); -#831 = DIRECTION('',(5.275122655165E-17,0.227455280238,0.97378852709)); -#832 = ORIENTED_EDGE('',*,*,#833,.F.); -#833 = EDGE_CURVE('',#618,#826,#834,.T.); -#834 = LINE('',#835,#836); -#835 = CARTESIAN_POINT('',(5.649679875255,3.602918464526,-13.21082950266 - )); -#836 = VECTOR('',#837,1.); -#837 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#838 = ORIENTED_EDGE('',*,*,#617,.T.); -#839 = ORIENTED_EDGE('',*,*,#840,.T.); -#840 = EDGE_CURVE('',#620,#824,#841,.T.); -#841 = LINE('',#842,#843); -#842 = CARTESIAN_POINT('',(1.103762571829,7.940067898719,-47.92064259636 - )); -#843 = VECTOR('',#844,1.); -#844 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#845 = PLANE('',#846); -#846 = AXIS2_PLACEMENT_3D('',#847,#848,#849); -#847 = CARTESIAN_POINT('',(5.823691883056,3.068404028665,-13.45978839622 - )); -#848 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02)); -#849 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487825E-02) - ); -#850 = ADVANCED_FACE('',(#851),#861,.F.); -#851 = FACE_BOUND('',#852,.F.); -#852 = EDGE_LOOP('',(#853,#854,#860)); -#853 = ORIENTED_EDGE('',*,*,#833,.T.); -#854 = ORIENTED_EDGE('',*,*,#855,.T.); -#855 = EDGE_CURVE('',#826,#628,#856,.T.); -#856 = LINE('',#857,#858); -#857 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#858 = VECTOR('',#859,1.); -#859 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#860 = ORIENTED_EDGE('',*,*,#627,.T.); -#861 = PLANE('',#862); -#862 = AXIS2_PLACEMENT_3D('',#863,#864,#865); -#863 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-13.01628215822 - )); -#864 = DIRECTION('',(2.88163763217E-16,0.342020143326,0.939692620786)); -#865 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326) - ); -#866 = ADVANCED_FACE('',(#867),#877,.F.); -#867 = FACE_BOUND('',#868,.F.); -#868 = EDGE_LOOP('',(#869,#875,#876)); -#869 = ORIENTED_EDGE('',*,*,#870,.T.); -#870 = EDGE_CURVE('',#636,#824,#871,.T.); -#871 = LINE('',#872,#873); -#872 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#873 = VECTOR('',#874,1.); -#874 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#875 = ORIENTED_EDGE('',*,*,#840,.F.); -#876 = ORIENTED_EDGE('',*,*,#643,.T.); -#877 = PLANE('',#878); -#878 = AXIS2_PLACEMENT_3D('',#879,#880,#881); -#879 = CARTESIAN_POINT('',(2.828438300639,3.068404028665,-49.69378323641 - )); -#880 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#881 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#882 = ADVANCED_FACE('',(#883),#889,.F.); -#883 = FACE_BOUND('',#884,.F.); -#884 = EDGE_LOOP('',(#885,#886,#887,#888)); -#885 = ORIENTED_EDGE('',*,*,#635,.T.); -#886 = ORIENTED_EDGE('',*,*,#855,.F.); -#887 = ORIENTED_EDGE('',*,*,#823,.F.); -#888 = ORIENTED_EDGE('',*,*,#870,.F.); -#889 = PLANE('',#890); -#890 = AXIS2_PLACEMENT_3D('',#891,#892,#893); -#891 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#892 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#893 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487825E-02)); -#894 = ADVANCED_FACE('',(#895),#914,.T.); -#895 = FACE_BOUND('',#896,.T.); -#896 = EDGE_LOOP('',(#897,#906,#912,#913)); -#897 = ORIENTED_EDGE('',*,*,#898,.T.); -#898 = EDGE_CURVE('',#899,#899,#901,.T.); -#899 = VERTEX_POINT('',#900); -#900 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#901 = CIRCLE('',#902,4.735522705283); -#902 = AXIS2_PLACEMENT_3D('',#903,#904,#905); -#903 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#904 = DIRECTION('',(-0.,1.,0.)); -#905 = DIRECTION('',(1.,0.,0.)); -#906 = ORIENTED_EDGE('',*,*,#907,.T.); -#907 = EDGE_CURVE('',#899,#652,#908,.T.); -#908 = LINE('',#909,#910); -#909 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#910 = VECTOR('',#911,1.); -#911 = DIRECTION('',(0.,1.,0.)); -#912 = ORIENTED_EDGE('',*,*,#651,.F.); -#913 = ORIENTED_EDGE('',*,*,#907,.F.); -#914 = CYLINDRICAL_SURFACE('',#915,4.735522705283); -#915 = AXIS2_PLACEMENT_3D('',#916,#917,#918); -#916 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#917 = DIRECTION('',(0.,1.,0.)); -#918 = DIRECTION('',(1.,0.,0.)); -#919 = ADVANCED_FACE('',(#920),#939,.T.); -#920 = FACE_BOUND('',#921,.T.); -#921 = EDGE_LOOP('',(#922,#931,#937,#938)); -#922 = ORIENTED_EDGE('',*,*,#923,.T.); -#923 = EDGE_CURVE('',#924,#924,#926,.T.); -#924 = VERTEX_POINT('',#925); -#925 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#926 = CIRCLE('',#927,4.735522705283); -#927 = AXIS2_PLACEMENT_3D('',#928,#929,#930); -#928 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#929 = DIRECTION('',(-0.,1.,0.)); -#930 = DIRECTION('',(1.,0.,0.)); -#931 = ORIENTED_EDGE('',*,*,#932,.T.); -#932 = EDGE_CURVE('',#924,#663,#933,.T.); -#933 = LINE('',#934,#935); -#934 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#935 = VECTOR('',#936,1.); -#936 = DIRECTION('',(0.,1.,0.)); -#937 = ORIENTED_EDGE('',*,*,#662,.F.); -#938 = ORIENTED_EDGE('',*,*,#932,.F.); -#939 = CYLINDRICAL_SURFACE('',#940,4.735522705283); -#940 = AXIS2_PLACEMENT_3D('',#941,#942,#943); -#941 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#942 = DIRECTION('',(0.,1.,0.)); -#943 = DIRECTION('',(1.,0.,0.)); -#944 = ADVANCED_FACE('',(#945),#953,.F.); -#945 = FACE_BOUND('',#946,.F.); -#946 = EDGE_LOOP('',(#947,#948,#949,#950,#951,#952)); -#947 = ORIENTED_EDGE('',*,*,#718,.T.); -#948 = ORIENTED_EDGE('',*,*,#687,.T.); -#949 = ORIENTED_EDGE('',*,*,#734,.T.); -#950 = ORIENTED_EDGE('',*,*,#782,.T.); -#951 = ORIENTED_EDGE('',*,*,#806,.T.); -#952 = ORIENTED_EDGE('',*,*,#758,.T.); -#953 = PLANE('',#954); -#954 = AXIS2_PLACEMENT_3D('',#955,#956,#957); -#955 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#956 = DIRECTION('',(0.,1.,0.)); -#957 = DIRECTION('',(0.,0.,1.)); -#958 = ADVANCED_FACE('',(#959),#962,.F.); -#959 = FACE_BOUND('',#960,.F.); -#960 = EDGE_LOOP('',(#961)); -#961 = ORIENTED_EDGE('',*,*,#898,.T.); -#962 = PLANE('',#963); -#963 = AXIS2_PLACEMENT_3D('',#964,#965,#966); -#964 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#965 = DIRECTION('',(0.,1.,0.)); -#966 = DIRECTION('',(0.,0.,1.)); -#967 = ADVANCED_FACE('',(#968),#971,.F.); -#968 = FACE_BOUND('',#969,.F.); -#969 = EDGE_LOOP('',(#970)); -#970 = ORIENTED_EDGE('',*,*,#923,.T.); -#971 = PLANE('',#972); -#972 = AXIS2_PLACEMENT_3D('',#973,#974,#975); -#973 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#974 = DIRECTION('',(0.,1.,0.)); -#975 = DIRECTION('',(0.,0.,1.)); -#976 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#980)) GLOBAL_UNIT_ASSIGNED_CONTEXT -((#977,#978,#979)) REPRESENTATION_CONTEXT('Context #1', - '3D Context with UNIT and UNCERTAINTY') ); -#977 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#978 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#979 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#980 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(5.E-06),#977, - 'distance_accuracy_value','confusion accuracy'); -#981 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl deleted file mode 100644 index 940dab90f7..0000000000 Binary files a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed.stl and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step deleted file mode 100644 index 14e61e2877..0000000000 --- a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.step +++ /dev/null @@ -1,1604 +0,0 @@ -ISO-10303-21; -HEADER; -FILE_DESCRIPTION(('FreeCAD Model'),'2;1'); -FILE_NAME('Open CASCADE Shape Model','2026-08-05T11:06:23',('FreeCAD'),( - 'FreeCAD'),'Open CASCADE STEP processor 7.8','FreeCAD','Unknown'); -FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }')); -ENDSEC; -DATA; -#1 = APPLICATION_PROTOCOL_DEFINITION('international standard', - 'automotive_design',2000,#2); -#2 = APPLICATION_CONTEXT( - 'core data for automotive mechanical design processes'); -#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10); -#4 = PRODUCT_DEFINITION_SHAPE('','',#5); -#5 = PRODUCT_DEFINITION('design','',#6,#9); -#6 = PRODUCT_DEFINITION_FORMATION('','',#7); -#7 = PRODUCT('Open CASCADE STEP translator 7.8 2', - 'Open CASCADE STEP translator 7.8 2','',(#8)); -#8 = PRODUCT_CONTEXT('',#2,'mechanical'); -#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design'); -#10 = ADVANCED_BREP_SHAPE_REPRESENTATION('',(#11,#15),#1522); -#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14); -#12 = CARTESIAN_POINT('',(0.,0.,0.)); -#13 = DIRECTION('',(0.,0.,1.)); -#14 = DIRECTION('',(1.,0.,-0.)); -#15 = MANIFOLD_SOLID_BREP('',#16); -#16 = CLOSED_SHELL('',(#17,#291,#322,#346,#370,#395,#419,#444,#468,#492, - #517,#541,#566,#590,#614,#638,#662,#679,#710,#734,#758,#782,#806, - #830,#854,#878,#903,#928,#952,#976,#1001,#1026,#1050,#1067,#1091, - #1221,#1252,#1276,#1300,#1324,#1348,#1365,#1390,#1421,#1437,#1454, - #1465,#1490,#1504,#1513)); -#17 = ADVANCED_FACE('',(#18,#152),#286,.F.); -#18 = FACE_BOUND('',#19,.F.); -#19 = EDGE_LOOP('',(#20,#30,#38,#46,#54,#62,#70,#79,#87,#96,#104,#112, - #121,#129,#138,#146)); -#20 = ORIENTED_EDGE('',*,*,#21,.F.); -#21 = EDGE_CURVE('',#22,#24,#26,.T.); -#22 = VERTEX_POINT('',#23); -#23 = CARTESIAN_POINT('',(28.536336768195,0.,-54.80352892379)); -#24 = VERTEX_POINT('',#25); -#25 = CARTESIAN_POINT('',(43.891390829132,0.,-6.628649129335)); -#26 = LINE('',#27,#28); -#27 = CARTESIAN_POINT('',(30.462276491561,4.440892098501E-16, - -48.76109401628)); -#28 = VECTOR('',#29,1.); -#29 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#30 = ORIENTED_EDGE('',*,*,#31,.F.); -#31 = EDGE_CURVE('',#32,#22,#34,.T.); -#32 = VERTEX_POINT('',#33); -#33 = CARTESIAN_POINT('',(34.683490155872,0.,-60.75238354821)); -#34 = LINE('',#35,#36); -#35 = CARTESIAN_POINT('',(13.469833011847,0.,-40.22304997814)); -#36 = VECTOR('',#37,1.); -#37 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#38 = ORIENTED_EDGE('',*,*,#39,.F.); -#39 = EDGE_CURVE('',#40,#32,#42,.T.); -#40 = VERTEX_POINT('',#41); -#41 = CARTESIAN_POINT('',(26.747616824317,0.,-68.95279080543)); -#42 = LINE('',#43,#44); -#43 = CARTESIAN_POINT('',(12.749348137648,0.,-83.41767694094)); -#44 = VECTOR('',#45,1.); -#45 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#46 = ORIENTED_EDGE('',*,*,#47,.F.); -#47 = EDGE_CURVE('',#48,#40,#50,.T.); -#48 = VERTEX_POINT('',#49); -#49 = CARTESIAN_POINT('',(19.965518143439,0.,-62.38947335481)); -#50 = LINE('',#51,#52); -#51 = CARTESIAN_POINT('',(8.607536374131,0.,-51.39788454757)); -#52 = VECTOR('',#53,1.); -#53 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#54 = ORIENTED_EDGE('',*,*,#55,.F.); -#55 = EDGE_CURVE('',#56,#48,#58,.T.); -#56 = VERTEX_POINT('',#57); -#57 = CARTESIAN_POINT('',(-19.96551814343,0.,-62.38947335481)); -#58 = LINE('',#59,#60); -#59 = CARTESIAN_POINT('',(-12.74971831875,0.,-62.38947335481)); -#60 = VECTOR('',#61,1.); -#61 = DIRECTION('',(1.,0.,0.)); -#62 = ORIENTED_EDGE('',*,*,#63,.T.); -#63 = EDGE_CURVE('',#56,#64,#66,.T.); -#64 = VERTEX_POINT('',#65); -#65 = CARTESIAN_POINT('',(-24.55693735351,0.,-66.83277965903)); -#66 = LINE('',#67,#68); -#67 = CARTESIAN_POINT('',(-30.98981424001,0.,-73.05814073287)); -#68 = VECTOR('',#69,1.); -#69 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#70 = ORIENTED_EDGE('',*,*,#71,.F.); -#71 = EDGE_CURVE('',#72,#64,#74,.T.); -#72 = VERTEX_POINT('',#73); -#73 = CARTESIAN_POINT('',(-28.86762797071,0.,-66.76211133463)); -#74 = CIRCLE('',#75,3.048528137424); -#75 = AXIS2_PLACEMENT_3D('',#76,#77,#78); -#76 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#77 = DIRECTION('',(0.,-1.,0.)); -#78 = DIRECTION('',(1.,0.,0.)); -#79 = ORIENTED_EDGE('',*,*,#80,.T.); -#80 = EDGE_CURVE('',#72,#81,#83,.T.); -#81 = VERTEX_POINT('',#82); -#82 = CARTESIAN_POINT('',(-30.0937101258,0.,-65.49515903052)); -#83 = LINE('',#84,#85); -#84 = CARTESIAN_POINT('',(-32.44179530228,0.,-63.0688029236)); -#85 = VECTOR('',#86,1.); -#86 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#87 = ORIENTED_EDGE('',*,*,#88,.F.); -#88 = EDGE_CURVE('',#89,#81,#91,.T.); -#89 = VERTEX_POINT('',#90); -#90 = CARTESIAN_POINT('',(-29.94071467356,0.,-56.16260351814)); -#91 = CIRCLE('',#92,6.6); -#92 = AXIS2_PLACEMENT_3D('',#93,#94,#95); -#93 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#94 = DIRECTION('',(0.,-1.,0.)); -#95 = DIRECTION('',(1.,0.,0.)); -#96 = ORIENTED_EDGE('',*,*,#97,.T.); -#97 = EDGE_CURVE('',#89,#98,#100,.T.); -#98 = VERTEX_POINT('',#99); -#99 = CARTESIAN_POINT('',(-28.53633676819,0.,-54.80352892379)); -#100 = LINE('',#101,#102); -#101 = CARTESIAN_POINT('',(-36.94745061313,0.,-62.94331173664)); -#102 = VECTOR('',#103,1.); -#103 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#104 = ORIENTED_EDGE('',*,*,#105,.T.); -#105 = EDGE_CURVE('',#98,#106,#108,.T.); -#106 = VERTEX_POINT('',#107); -#107 = CARTESIAN_POINT('',(-42.51292396981,0.,-10.95344505546)); -#108 = LINE('',#109,#110); -#109 = CARTESIAN_POINT('',(-33.96596941491,4.440892098501E-16, - -37.76862308461)); -#110 = VECTOR('',#111,1.); -#111 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#112 = ORIENTED_EDGE('',*,*,#113,.F.); -#113 = EDGE_CURVE('',#114,#106,#116,.T.); -#114 = VERTEX_POINT('',#115); -#115 = CARTESIAN_POINT('',(-40.68171555857,0.,-3.418973858775)); -#116 = CIRCLE('',#117,7.454044962965); -#117 = AXIS2_PLACEMENT_3D('',#118,#119,#120); -#118 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#119 = DIRECTION('',(0.,-1.,0.)); -#120 = DIRECTION('',(1.,0.,0.)); -#121 = ORIENTED_EDGE('',*,*,#122,.T.); -#122 = EDGE_CURVE('',#114,#123,#125,.T.); -#123 = VERTEX_POINT('',#124); -#124 = CARTESIAN_POINT('',(-37.84598092218,0.,-0.583239222383)); -#125 = LINE('',#126,#127); -#126 = CARTESIAN_POINT('',(-57.34820403576,0.,-20.08546233597)); -#127 = VECTOR('',#128,1.); -#128 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#129 = ORIENTED_EDGE('',*,*,#130,.F.); -#130 = EDGE_CURVE('',#131,#123,#133,.T.); -#131 = VERTEX_POINT('',#132); -#132 = CARTESIAN_POINT('',(-32.57517518159,0.,1.6)); -#133 = CIRCLE('',#134,7.454044962965); -#134 = AXIS2_PLACEMENT_3D('',#135,#136,#137); -#135 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#136 = DIRECTION('',(0.,-1.,0.)); -#137 = DIRECTION('',(1.,0.,0.)); -#138 = ORIENTED_EDGE('',*,*,#139,.T.); -#139 = EDGE_CURVE('',#131,#140,#142,.T.); -#140 = VERTEX_POINT('',#141); -#141 = CARTESIAN_POINT('',(35.662741699797,0.,1.6)); -#142 = LINE('',#143,#144); -#143 = CARTESIAN_POINT('',(-4.901106540577,0.,1.6)); -#144 = VECTOR('',#145,1.); -#145 = DIRECTION('',(1.,0.,0.)); -#146 = ORIENTED_EDGE('',*,*,#147,.F.); -#147 = EDGE_CURVE('',#24,#140,#148,.T.); -#148 = LINE('',#149,#150); -#149 = CARTESIAN_POINT('',(33.5241070341,0.,3.738634665697)); -#150 = VECTOR('',#151,1.); -#151 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#152 = FACE_BOUND('',#153,.F.); -#153 = EDGE_LOOP('',(#154,#164,#172,#180,#188,#197,#205,#214,#222,#230, - #239,#247,#256,#264,#272,#280)); -#154 = ORIENTED_EDGE('',*,*,#155,.T.); -#155 = EDGE_CURVE('',#156,#158,#160,.T.); -#156 = VERTEX_POINT('',#157); -#157 = CARTESIAN_POINT('',(32.703857168398,0.,-60.78483712899)); -#158 = VERTEX_POINT('',#159); -#159 = CARTESIAN_POINT('',(26.938753236523,0.,-55.20570756731)); -#160 = LINE('',#161,#162); -#161 = CARTESIAN_POINT('',(13.567306766147,0.,-42.26560567724)); -#162 = VECTOR('',#163,1.); -#163 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#164 = ORIENTED_EDGE('',*,*,#165,.T.); -#165 = EDGE_CURVE('',#158,#166,#168,.T.); -#166 = VERTEX_POINT('',#167); -#167 = CARTESIAN_POINT('',(42.298608189024,0.,-7.015765476549)); -#168 = LINE('',#169,#170); -#169 = CARTESIAN_POINT('',(25.140315874087,-4.440892098501E-16, - -60.84811712245)); -#170 = VECTOR('',#171,1.); -#171 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#172 = ORIENTED_EDGE('',*,*,#173,.T.); -#173 = EDGE_CURVE('',#166,#174,#176,.T.); -#174 = VERTEX_POINT('',#175); -#175 = CARTESIAN_POINT('',(35.082842712475,0.,0.2)); -#176 = LINE('',#177,#178); -#177 = CARTESIAN_POINT('',(34.536239068456,0.,0.746603644019)); -#178 = VECTOR('',#179,1.); -#179 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#180 = ORIENTED_EDGE('',*,*,#181,.F.); -#181 = EDGE_CURVE('',#182,#174,#184,.T.); -#182 = VERTEX_POINT('',#183); -#183 = CARTESIAN_POINT('',(-32.57517518159,0.,0.2)); -#184 = LINE('',#185,#186); -#185 = CARTESIAN_POINT('',(-30.87627118587,0.,0.2)); -#186 = VECTOR('',#187,1.); -#187 = DIRECTION('',(1.,0.,0.)); -#188 = ORIENTED_EDGE('',*,*,#189,.T.); -#189 = EDGE_CURVE('',#182,#190,#192,.T.); -#190 = VERTEX_POINT('',#191); -#191 = CARTESIAN_POINT('',(-36.85603142851,0.,-1.573188716044)); -#192 = CIRCLE('',#193,6.054044962965); -#193 = AXIS2_PLACEMENT_3D('',#194,#195,#196); -#194 = CARTESIAN_POINT('',(-32.57517518159,0.,-5.854044962965)); -#195 = DIRECTION('',(0.,-1.,0.)); -#196 = DIRECTION('',(-1.,0.,0.)); -#197 = ORIENTED_EDGE('',*,*,#198,.F.); -#198 = EDGE_CURVE('',#199,#190,#201,.T.); -#199 = VERTEX_POINT('',#200); -#200 = CARTESIAN_POINT('',(-39.69176606491,0.,-4.408923352436)); -#201 = LINE('',#202,#203); -#202 = CARTESIAN_POINT('',(-57.0671882012,0.,-21.78434548873)); -#203 = VECTOR('',#204,1.); -#204 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#205 = ORIENTED_EDGE('',*,*,#206,.T.); -#206 = EDGE_CURVE('',#199,#207,#209,.T.); -#207 = VERTEX_POINT('',#208); -#208 = CARTESIAN_POINT('',(-41.17904151244,0.,-10.52828909594)); -#209 = CIRCLE('',#210,6.054044962965); -#210 = AXIS2_PLACEMENT_3D('',#211,#212,#213); -#211 = CARTESIAN_POINT('',(-35.41090981799,0.,-8.689779599357)); -#212 = DIRECTION('',(0.,-1.,0.)); -#213 = DIRECTION('',(-1.,0.,0.)); -#214 = ORIENTED_EDGE('',*,*,#215,.F.); -#215 = EDGE_CURVE('',#216,#207,#218,.T.); -#216 = VERTEX_POINT('',#217); -#217 = CARTESIAN_POINT('',(-26.93875323652,0.,-55.20570756731)); -#218 = LINE('',#219,#220); -#219 = CARTESIAN_POINT('',(-29.06259699304,-4.440892098501E-16, - -48.54236940733)); -#220 = VECTOR('',#221,1.); -#221 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#222 = ORIENTED_EDGE('',*,*,#223,.F.); -#223 = EDGE_CURVE('',#224,#216,#226,.T.); -#224 = VERTEX_POINT('',#225); -#225 = CARTESIAN_POINT('',(-28.96712497021,0.,-57.16864680227)); -#226 = LINE('',#227,#228); -#227 = CARTESIAN_POINT('',(-36.14667143517,0.,-64.11659091489)); -#228 = VECTOR('',#229,1.); -#229 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#230 = ORIENTED_EDGE('',*,*,#231,.T.); -#231 = EDGE_CURVE('',#224,#232,#234,.T.); -#232 = VERTEX_POINT('',#233); -#233 = CARTESIAN_POINT('',(-29.08766684168,0.,-64.52156932717)); -#234 = CIRCLE('',#235,5.2); -#235 = AXIS2_PLACEMENT_3D('',#236,#237,#238); -#236 = CARTESIAN_POINT('',(-25.35093464349,0.,-60.90537900045)); -#237 = DIRECTION('',(0.,-1.,0.)); -#238 = DIRECTION('',(-1.,0.,0.)); -#239 = ORIENTED_EDGE('',*,*,#240,.F.); -#240 = EDGE_CURVE('',#241,#232,#243,.T.); -#241 = VERTEX_POINT('',#242); -#242 = CARTESIAN_POINT('',(-27.86158468659,0.,-65.78852163128)); -#243 = LINE('',#244,#245); -#244 = CARTESIAN_POINT('',(-31.12923147938,0.,-62.41195129628)); -#245 = VECTOR('',#246,1.); -#246 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#247 = ORIENTED_EDGE('',*,*,#248,.T.); -#248 = EDGE_CURVE('',#241,#249,#251,.T.); -#249 = VERTEX_POINT('',#250); -#250 = CARTESIAN_POINT('',(-25.53052705686,0.,-65.82673637491)); -#251 = CIRCLE('',#252,1.648528137424); -#252 = AXIS2_PLACEMENT_3D('',#253,#254,#255); -#253 = CARTESIAN_POINT('',(-26.67694849991,0.,-64.64210018823)); -#254 = DIRECTION('',(0.,-1.,0.)); -#255 = DIRECTION('',(-1.,0.,0.)); -#256 = ORIENTED_EDGE('',*,*,#257,.F.); -#257 = EDGE_CURVE('',#258,#249,#260,.T.); -#258 = VERTEX_POINT('',#259); -#259 = CARTESIAN_POINT('',(-20.53201900137,0.,-60.98947335481)); -#260 = LINE('',#261,#262); -#261 = CARTESIAN_POINT('',(-30.69923804215,0.,-70.82871181101)); -#262 = VECTOR('',#263,1.); -#263 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#264 = ORIENTED_EDGE('',*,*,#265,.T.); -#265 = EDGE_CURVE('',#258,#266,#268,.T.); -#266 = VERTEX_POINT('',#267); -#267 = CARTESIAN_POINT('',(20.532019001374,0.,-60.98947335481)); -#268 = LINE('',#269,#270); -#269 = CARTESIAN_POINT('',(-17.57924046663,0.,-60.98947335481)); -#270 = VECTOR('',#271,1.); -#271 = DIRECTION('',(1.,0.,0.)); -#272 = ORIENTED_EDGE('',*,*,#273,.T.); -#273 = EDGE_CURVE('',#266,#274,#276,.T.); -#274 = VERTEX_POINT('',#275); -#275 = CARTESIAN_POINT('',(26.715163243538,0.,-66.97315781796)); -#276 = LINE('',#277,#278); -#277 = CARTESIAN_POINT('',(7.481849370247,-4.440892098501E-16, - -48.36028435244)); -#278 = VECTOR('',#279,1.); -#279 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#280 = ORIENTED_EDGE('',*,*,#281,.T.); -#281 = EDGE_CURVE('',#274,#156,#282,.T.); -#282 = LINE('',#283,#284); -#283 = CARTESIAN_POINT('',(9.75933652063,0.,-84.4941890519)); -#284 = VECTOR('',#285,1.); -#285 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#286 = PLANE('',#287); -#287 = AXIS2_PLACEMENT_3D('',#288,#289,#290); -#288 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#289 = DIRECTION('',(0.,1.,0.)); -#290 = DIRECTION('',(0.,0.,1.)); -#291 = ADVANCED_FACE('',(#292),#317,.F.); -#292 = FACE_BOUND('',#293,.F.); -#293 = EDGE_LOOP('',(#294,#295,#303,#311)); -#294 = ORIENTED_EDGE('',*,*,#21,.T.); -#295 = ORIENTED_EDGE('',*,*,#296,.T.); -#296 = EDGE_CURVE('',#24,#297,#299,.T.); -#297 = VERTEX_POINT('',#298); -#298 = CARTESIAN_POINT('',(43.891390829132,20.8572529153,-6.628649129335 - )); -#299 = LINE('',#300,#301); -#300 = CARTESIAN_POINT('',(43.891390829132,-5.,-6.628649129335)); -#301 = VECTOR('',#302,1.); -#302 = DIRECTION('',(0.,1.,0.)); -#303 = ORIENTED_EDGE('',*,*,#304,.F.); -#304 = EDGE_CURVE('',#305,#297,#307,.T.); -#305 = VERTEX_POINT('',#306); -#306 = CARTESIAN_POINT('',(28.536336768195,20.8572529153,-54.80352892379 - )); -#307 = LINE('',#308,#309); -#308 = CARTESIAN_POINT('',(30.462276491561,20.8572529153,-48.76109401628 - )); -#309 = VECTOR('',#310,1.); -#310 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#311 = ORIENTED_EDGE('',*,*,#312,.F.); -#312 = EDGE_CURVE('',#22,#305,#313,.T.); -#313 = LINE('',#314,#315); -#314 = CARTESIAN_POINT('',(28.536336768195,-5.,-54.80352892379)); -#315 = VECTOR('',#316,1.); -#316 = DIRECTION('',(0.,1.,0.)); -#317 = PLANE('',#318); -#318 = AXIS2_PLACEMENT_3D('',#319,#320,#321); -#319 = CARTESIAN_POINT('',(43.891390829132,-5.,-6.628649129335)); -#320 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#321 = DIRECTION('',(-0.30368282823,0.,-0.952773183837)); -#322 = ADVANCED_FACE('',(#323),#341,.F.); -#323 = FACE_BOUND('',#324,.F.); -#324 = EDGE_LOOP('',(#325,#326,#334,#340)); -#325 = ORIENTED_EDGE('',*,*,#147,.T.); -#326 = ORIENTED_EDGE('',*,*,#327,.T.); -#327 = EDGE_CURVE('',#140,#328,#330,.T.); -#328 = VERTEX_POINT('',#329); -#329 = CARTESIAN_POINT('',(35.662741699797,20.8572529153,1.6)); -#330 = LINE('',#331,#332); -#331 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#332 = VECTOR('',#333,1.); -#333 = DIRECTION('',(0.,1.,0.)); -#334 = ORIENTED_EDGE('',*,*,#335,.F.); -#335 = EDGE_CURVE('',#297,#328,#336,.T.); -#336 = LINE('',#337,#338); -#337 = CARTESIAN_POINT('',(33.5241070341,20.8572529153,3.738634665697)); -#338 = VECTOR('',#339,1.); -#339 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#340 = ORIENTED_EDGE('',*,*,#296,.F.); -#341 = PLANE('',#342); -#342 = AXIS2_PLACEMENT_3D('',#343,#344,#345); -#343 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#344 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#345 = DIRECTION('',(0.707106781187,0.,-0.707106781187)); -#346 = ADVANCED_FACE('',(#347),#365,.T.); -#347 = FACE_BOUND('',#348,.T.); -#348 = EDGE_LOOP('',(#349,#350,#351,#359)); -#349 = ORIENTED_EDGE('',*,*,#139,.T.); -#350 = ORIENTED_EDGE('',*,*,#327,.T.); -#351 = ORIENTED_EDGE('',*,*,#352,.F.); -#352 = EDGE_CURVE('',#353,#328,#355,.T.); -#353 = VERTEX_POINT('',#354); -#354 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,1.6)); -#355 = LINE('',#356,#357); -#356 = CARTESIAN_POINT('',(-4.901106540577,20.8572529153,1.6)); -#357 = VECTOR('',#358,1.); -#358 = DIRECTION('',(1.,0.,0.)); -#359 = ORIENTED_EDGE('',*,*,#360,.F.); -#360 = EDGE_CURVE('',#131,#353,#361,.T.); -#361 = LINE('',#362,#363); -#362 = CARTESIAN_POINT('',(-32.57517518159,-5.,1.6)); -#363 = VECTOR('',#364,1.); -#364 = DIRECTION('',(0.,1.,0.)); -#365 = PLANE('',#366); -#366 = AXIS2_PLACEMENT_3D('',#367,#368,#369); -#367 = CARTESIAN_POINT('',(35.662741699797,-5.,1.6)); -#368 = DIRECTION('',(0.,0.,1.)); -#369 = DIRECTION('',(-1.,0.,0.)); -#370 = ADVANCED_FACE('',(#371),#390,.T.); -#371 = FACE_BOUND('',#372,.F.); -#372 = EDGE_LOOP('',(#373,#374,#382,#389)); -#373 = ORIENTED_EDGE('',*,*,#130,.T.); -#374 = ORIENTED_EDGE('',*,*,#375,.T.); -#375 = EDGE_CURVE('',#123,#376,#378,.T.); -#376 = VERTEX_POINT('',#377); -#377 = CARTESIAN_POINT('',(-37.84598092218,20.8572529153,-0.583239222383 - )); -#378 = LINE('',#379,#380); -#379 = CARTESIAN_POINT('',(-37.84598092218,-5.,-0.583239222383)); -#380 = VECTOR('',#381,1.); -#381 = DIRECTION('',(0.,1.,0.)); -#382 = ORIENTED_EDGE('',*,*,#383,.F.); -#383 = EDGE_CURVE('',#353,#376,#384,.T.); -#384 = CIRCLE('',#385,7.454044962965); -#385 = AXIS2_PLACEMENT_3D('',#386,#387,#388); -#386 = CARTESIAN_POINT('',(-32.57517518159,20.8572529153,-5.854044962965 - )); -#387 = DIRECTION('',(0.,-1.,0.)); -#388 = DIRECTION('',(1.,0.,0.)); -#389 = ORIENTED_EDGE('',*,*,#360,.F.); -#390 = CYLINDRICAL_SURFACE('',#391,7.454044962965); -#391 = AXIS2_PLACEMENT_3D('',#392,#393,#394); -#392 = CARTESIAN_POINT('',(-32.57517518159,-5.,-5.854044962965)); -#393 = DIRECTION('',(0.,-1.,0.)); -#394 = DIRECTION('',(1.,0.,0.)); -#395 = ADVANCED_FACE('',(#396),#414,.T.); -#396 = FACE_BOUND('',#397,.T.); -#397 = EDGE_LOOP('',(#398,#399,#400,#408)); -#398 = ORIENTED_EDGE('',*,*,#122,.T.); -#399 = ORIENTED_EDGE('',*,*,#375,.T.); -#400 = ORIENTED_EDGE('',*,*,#401,.F.); -#401 = EDGE_CURVE('',#402,#376,#404,.T.); -#402 = VERTEX_POINT('',#403); -#403 = CARTESIAN_POINT('',(-40.68171555857,20.8572529153,-3.418973858775 - )); -#404 = LINE('',#405,#406); -#405 = CARTESIAN_POINT('',(-57.34820403576,20.8572529153,-20.08546233597 - )); -#406 = VECTOR('',#407,1.); -#407 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#408 = ORIENTED_EDGE('',*,*,#409,.F.); -#409 = EDGE_CURVE('',#114,#402,#410,.T.); -#410 = LINE('',#411,#412); -#411 = CARTESIAN_POINT('',(-40.68171555857,-5.,-3.418973858775)); -#412 = VECTOR('',#413,1.); -#413 = DIRECTION('',(0.,1.,0.)); -#414 = PLANE('',#415); -#415 = AXIS2_PLACEMENT_3D('',#416,#417,#418); -#416 = CARTESIAN_POINT('',(-37.84598092218,-5.,-0.583239222383)); -#417 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#418 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#419 = ADVANCED_FACE('',(#420),#439,.T.); -#420 = FACE_BOUND('',#421,.F.); -#421 = EDGE_LOOP('',(#422,#423,#431,#438)); -#422 = ORIENTED_EDGE('',*,*,#113,.T.); -#423 = ORIENTED_EDGE('',*,*,#424,.T.); -#424 = EDGE_CURVE('',#106,#425,#427,.T.); -#425 = VERTEX_POINT('',#426); -#426 = CARTESIAN_POINT('',(-42.51292396981,20.8572529153,-10.95344505546 - )); -#427 = LINE('',#428,#429); -#428 = CARTESIAN_POINT('',(-42.51292396981,-5.,-10.95344505546)); -#429 = VECTOR('',#430,1.); -#430 = DIRECTION('',(0.,1.,0.)); -#431 = ORIENTED_EDGE('',*,*,#432,.F.); -#432 = EDGE_CURVE('',#402,#425,#433,.T.); -#433 = CIRCLE('',#434,7.454044962965); -#434 = AXIS2_PLACEMENT_3D('',#435,#436,#437); -#435 = CARTESIAN_POINT('',(-35.41090981799,20.8572529153,-8.689779599357 - )); -#436 = DIRECTION('',(0.,-1.,0.)); -#437 = DIRECTION('',(1.,0.,0.)); -#438 = ORIENTED_EDGE('',*,*,#409,.F.); -#439 = CYLINDRICAL_SURFACE('',#440,7.454044962965); -#440 = AXIS2_PLACEMENT_3D('',#441,#442,#443); -#441 = CARTESIAN_POINT('',(-35.41090981799,-5.,-8.689779599357)); -#442 = DIRECTION('',(0.,-1.,0.)); -#443 = DIRECTION('',(1.,0.,0.)); -#444 = ADVANCED_FACE('',(#445),#463,.T.); -#445 = FACE_BOUND('',#446,.T.); -#446 = EDGE_LOOP('',(#447,#448,#449,#457)); -#447 = ORIENTED_EDGE('',*,*,#105,.T.); -#448 = ORIENTED_EDGE('',*,*,#424,.T.); -#449 = ORIENTED_EDGE('',*,*,#450,.F.); -#450 = EDGE_CURVE('',#451,#425,#453,.T.); -#451 = VERTEX_POINT('',#452); -#452 = CARTESIAN_POINT('',(-28.53633676819,20.8572529153,-54.80352892379 - )); -#453 = LINE('',#454,#455); -#454 = CARTESIAN_POINT('',(-33.96596941491,20.8572529153,-37.76862308461 - )); -#455 = VECTOR('',#456,1.); -#456 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#457 = ORIENTED_EDGE('',*,*,#458,.F.); -#458 = EDGE_CURVE('',#98,#451,#459,.T.); -#459 = LINE('',#460,#461); -#460 = CARTESIAN_POINT('',(-28.53633676819,-5.,-54.80352892379)); -#461 = VECTOR('',#462,1.); -#462 = DIRECTION('',(0.,1.,0.)); -#463 = PLANE('',#464); -#464 = AXIS2_PLACEMENT_3D('',#465,#466,#467); -#465 = CARTESIAN_POINT('',(-42.51292396981,-5.,-10.95344505546)); -#466 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#467 = DIRECTION('',(0.30368282823,0.,-0.952773183837)); -#468 = ADVANCED_FACE('',(#469),#487,.T.); -#469 = FACE_BOUND('',#470,.T.); -#470 = EDGE_LOOP('',(#471,#472,#473,#481)); -#471 = ORIENTED_EDGE('',*,*,#97,.T.); -#472 = ORIENTED_EDGE('',*,*,#458,.T.); -#473 = ORIENTED_EDGE('',*,*,#474,.F.); -#474 = EDGE_CURVE('',#475,#451,#477,.T.); -#475 = VERTEX_POINT('',#476); -#476 = CARTESIAN_POINT('',(-29.94071467356,20.8572529153,-56.16260351814 - )); -#477 = LINE('',#478,#479); -#478 = CARTESIAN_POINT('',(-36.94745061313,20.8572529153,-62.94331173664 - )); -#479 = VECTOR('',#480,1.); -#480 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#481 = ORIENTED_EDGE('',*,*,#482,.F.); -#482 = EDGE_CURVE('',#89,#475,#483,.T.); -#483 = LINE('',#484,#485); -#484 = CARTESIAN_POINT('',(-29.94071467356,-5.,-56.16260351814)); -#485 = VECTOR('',#486,1.); -#486 = DIRECTION('',(0.,1.,0.)); -#487 = PLANE('',#488); -#488 = AXIS2_PLACEMENT_3D('',#489,#490,#491); -#489 = CARTESIAN_POINT('',(-28.53633676819,-5.,-54.80352892379)); -#490 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#491 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#492 = ADVANCED_FACE('',(#493),#512,.T.); -#493 = FACE_BOUND('',#494,.F.); -#494 = EDGE_LOOP('',(#495,#496,#504,#511)); -#495 = ORIENTED_EDGE('',*,*,#88,.T.); -#496 = ORIENTED_EDGE('',*,*,#497,.T.); -#497 = EDGE_CURVE('',#81,#498,#500,.T.); -#498 = VERTEX_POINT('',#499); -#499 = CARTESIAN_POINT('',(-30.0937101258,20.8572529153,-65.49515903052) - ); -#500 = LINE('',#501,#502); -#501 = CARTESIAN_POINT('',(-30.0937101258,-5.,-65.49515903052)); -#502 = VECTOR('',#503,1.); -#503 = DIRECTION('',(0.,1.,0.)); -#504 = ORIENTED_EDGE('',*,*,#505,.F.); -#505 = EDGE_CURVE('',#475,#498,#506,.T.); -#506 = CIRCLE('',#507,6.6); -#507 = AXIS2_PLACEMENT_3D('',#508,#509,#510); -#508 = CARTESIAN_POINT('',(-25.35093464349,20.8572529153,-60.90537900045 - )); -#509 = DIRECTION('',(0.,-1.,0.)); -#510 = DIRECTION('',(1.,0.,0.)); -#511 = ORIENTED_EDGE('',*,*,#482,.F.); -#512 = CYLINDRICAL_SURFACE('',#513,6.6); -#513 = AXIS2_PLACEMENT_3D('',#514,#515,#516); -#514 = CARTESIAN_POINT('',(-25.35093464349,-5.,-60.90537900045)); -#515 = DIRECTION('',(0.,-1.,0.)); -#516 = DIRECTION('',(1.,0.,0.)); -#517 = ADVANCED_FACE('',(#518),#536,.T.); -#518 = FACE_BOUND('',#519,.T.); -#519 = EDGE_LOOP('',(#520,#521,#522,#530)); -#520 = ORIENTED_EDGE('',*,*,#80,.T.); -#521 = ORIENTED_EDGE('',*,*,#497,.T.); -#522 = ORIENTED_EDGE('',*,*,#523,.F.); -#523 = EDGE_CURVE('',#524,#498,#526,.T.); -#524 = VERTEX_POINT('',#525); -#525 = CARTESIAN_POINT('',(-28.86762797071,20.8572529153,-66.76211133463 - )); -#526 = LINE('',#527,#528); -#527 = CARTESIAN_POINT('',(-32.44179530228,20.8572529153,-63.0688029236) - ); -#528 = VECTOR('',#529,1.); -#529 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#530 = ORIENTED_EDGE('',*,*,#531,.F.); -#531 = EDGE_CURVE('',#72,#524,#532,.T.); -#532 = LINE('',#533,#534); -#533 = CARTESIAN_POINT('',(-28.86762797071,-5.,-66.76211133463)); -#534 = VECTOR('',#535,1.); -#535 = DIRECTION('',(0.,1.,0.)); -#536 = PLANE('',#537); -#537 = AXIS2_PLACEMENT_3D('',#538,#539,#540); -#538 = CARTESIAN_POINT('',(-30.0937101258,-5.,-65.49515903052)); -#539 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#540 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#541 = ADVANCED_FACE('',(#542),#561,.T.); -#542 = FACE_BOUND('',#543,.F.); -#543 = EDGE_LOOP('',(#544,#545,#553,#560)); -#544 = ORIENTED_EDGE('',*,*,#71,.T.); -#545 = ORIENTED_EDGE('',*,*,#546,.T.); -#546 = EDGE_CURVE('',#64,#547,#549,.T.); -#547 = VERTEX_POINT('',#548); -#548 = CARTESIAN_POINT('',(-24.55693735351,20.8572529153,-66.83277965903 - )); -#549 = LINE('',#550,#551); -#550 = CARTESIAN_POINT('',(-24.55693735351,-5.,-66.83277965903)); -#551 = VECTOR('',#552,1.); -#552 = DIRECTION('',(0.,1.,0.)); -#553 = ORIENTED_EDGE('',*,*,#554,.F.); -#554 = EDGE_CURVE('',#524,#547,#555,.T.); -#555 = CIRCLE('',#556,3.048528137424); -#556 = AXIS2_PLACEMENT_3D('',#557,#558,#559); -#557 = CARTESIAN_POINT('',(-26.67694849991,20.8572529153,-64.64210018823 - )); -#558 = DIRECTION('',(0.,-1.,0.)); -#559 = DIRECTION('',(1.,0.,0.)); -#560 = ORIENTED_EDGE('',*,*,#531,.F.); -#561 = CYLINDRICAL_SURFACE('',#562,3.048528137424); -#562 = AXIS2_PLACEMENT_3D('',#563,#564,#565); -#563 = CARTESIAN_POINT('',(-26.67694849991,-5.,-64.64210018823)); -#564 = DIRECTION('',(0.,-1.,0.)); -#565 = DIRECTION('',(1.,0.,0.)); -#566 = ADVANCED_FACE('',(#567),#585,.T.); -#567 = FACE_BOUND('',#568,.T.); -#568 = EDGE_LOOP('',(#569,#570,#571,#579)); -#569 = ORIENTED_EDGE('',*,*,#63,.T.); -#570 = ORIENTED_EDGE('',*,*,#546,.T.); -#571 = ORIENTED_EDGE('',*,*,#572,.F.); -#572 = EDGE_CURVE('',#573,#547,#575,.T.); -#573 = VERTEX_POINT('',#574); -#574 = CARTESIAN_POINT('',(-19.96551814343,20.8572529153,-62.38947335481 - )); -#575 = LINE('',#576,#577); -#576 = CARTESIAN_POINT('',(-30.98981424001,20.8572529153,-73.05814073287 - )); -#577 = VECTOR('',#578,1.); -#578 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#579 = ORIENTED_EDGE('',*,*,#580,.F.); -#580 = EDGE_CURVE('',#56,#573,#581,.T.); -#581 = LINE('',#582,#583); -#582 = CARTESIAN_POINT('',(-19.96551814343,-5.,-62.38947335481)); -#583 = VECTOR('',#584,1.); -#584 = DIRECTION('',(0.,1.,0.)); -#585 = PLANE('',#586); -#586 = AXIS2_PLACEMENT_3D('',#587,#588,#589); -#587 = CARTESIAN_POINT('',(-24.55693735351,-5.,-66.83277965903)); -#588 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#589 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#590 = ADVANCED_FACE('',(#591),#609,.F.); -#591 = FACE_BOUND('',#592,.F.); -#592 = EDGE_LOOP('',(#593,#594,#602,#608)); -#593 = ORIENTED_EDGE('',*,*,#55,.T.); -#594 = ORIENTED_EDGE('',*,*,#595,.T.); -#595 = EDGE_CURVE('',#48,#596,#598,.T.); -#596 = VERTEX_POINT('',#597); -#597 = CARTESIAN_POINT('',(19.965518143439,20.8572529153,-62.38947335481 - )); -#598 = LINE('',#599,#600); -#599 = CARTESIAN_POINT('',(19.965518143439,-5.,-62.38947335481)); -#600 = VECTOR('',#601,1.); -#601 = DIRECTION('',(0.,1.,0.)); -#602 = ORIENTED_EDGE('',*,*,#603,.F.); -#603 = EDGE_CURVE('',#573,#596,#604,.T.); -#604 = LINE('',#605,#606); -#605 = CARTESIAN_POINT('',(-12.74971831875,20.8572529153,-62.38947335481 - )); -#606 = VECTOR('',#607,1.); -#607 = DIRECTION('',(1.,0.,0.)); -#608 = ORIENTED_EDGE('',*,*,#580,.F.); -#609 = PLANE('',#610); -#610 = AXIS2_PLACEMENT_3D('',#611,#612,#613); -#611 = CARTESIAN_POINT('',(19.965518143439,-5.,-62.38947335481)); -#612 = DIRECTION('',(0.,0.,1.)); -#613 = DIRECTION('',(-1.,0.,0.)); -#614 = ADVANCED_FACE('',(#615),#633,.F.); -#615 = FACE_BOUND('',#616,.F.); -#616 = EDGE_LOOP('',(#617,#618,#626,#632)); -#617 = ORIENTED_EDGE('',*,*,#47,.T.); -#618 = ORIENTED_EDGE('',*,*,#619,.T.); -#619 = EDGE_CURVE('',#40,#620,#622,.T.); -#620 = VERTEX_POINT('',#621); -#621 = CARTESIAN_POINT('',(26.747616824317,20.8572529153,-68.95279080543 - )); -#622 = LINE('',#623,#624); -#623 = CARTESIAN_POINT('',(26.747616824317,-5.,-68.95279080543)); -#624 = VECTOR('',#625,1.); -#625 = DIRECTION('',(0.,1.,0.)); -#626 = ORIENTED_EDGE('',*,*,#627,.F.); -#627 = EDGE_CURVE('',#596,#620,#628,.T.); -#628 = LINE('',#629,#630); -#629 = CARTESIAN_POINT('',(8.607536374131,20.8572529153,-51.39788454757) - ); -#630 = VECTOR('',#631,1.); -#631 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#632 = ORIENTED_EDGE('',*,*,#595,.F.); -#633 = PLANE('',#634); -#634 = AXIS2_PLACEMENT_3D('',#635,#636,#637); -#635 = CARTESIAN_POINT('',(26.747616824317,-5.,-68.95279080543)); -#636 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#637 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#638 = ADVANCED_FACE('',(#639),#657,.F.); -#639 = FACE_BOUND('',#640,.F.); -#640 = EDGE_LOOP('',(#641,#642,#650,#656)); -#641 = ORIENTED_EDGE('',*,*,#39,.T.); -#642 = ORIENTED_EDGE('',*,*,#643,.T.); -#643 = EDGE_CURVE('',#32,#644,#646,.T.); -#644 = VERTEX_POINT('',#645); -#645 = CARTESIAN_POINT('',(34.683490155872,20.8572529153,-60.75238354821 - )); -#646 = LINE('',#647,#648); -#647 = CARTESIAN_POINT('',(34.683490155872,-5.,-60.75238354821)); -#648 = VECTOR('',#649,1.); -#649 = DIRECTION('',(0.,1.,0.)); -#650 = ORIENTED_EDGE('',*,*,#651,.F.); -#651 = EDGE_CURVE('',#620,#644,#652,.T.); -#652 = LINE('',#653,#654); -#653 = CARTESIAN_POINT('',(12.749348137648,20.8572529153,-83.41767694094 - )); -#654 = VECTOR('',#655,1.); -#655 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#656 = ORIENTED_EDGE('',*,*,#619,.F.); -#657 = PLANE('',#658); -#658 = AXIS2_PLACEMENT_3D('',#659,#660,#661); -#659 = CARTESIAN_POINT('',(34.683490155872,-5.,-60.75238354821)); -#660 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#661 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#662 = ADVANCED_FACE('',(#663),#674,.F.); -#663 = FACE_BOUND('',#664,.F.); -#664 = EDGE_LOOP('',(#665,#666,#667,#673)); -#665 = ORIENTED_EDGE('',*,*,#31,.T.); -#666 = ORIENTED_EDGE('',*,*,#312,.T.); -#667 = ORIENTED_EDGE('',*,*,#668,.F.); -#668 = EDGE_CURVE('',#644,#305,#669,.T.); -#669 = LINE('',#670,#671); -#670 = CARTESIAN_POINT('',(13.469833011847,20.8572529153,-40.22304997814 - )); -#671 = VECTOR('',#672,1.); -#672 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#673 = ORIENTED_EDGE('',*,*,#643,.F.); -#674 = PLANE('',#675); -#675 = AXIS2_PLACEMENT_3D('',#676,#677,#678); -#676 = CARTESIAN_POINT('',(28.536336768195,-5.,-54.80352892379)); -#677 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#678 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#679 = ADVANCED_FACE('',(#680),#705,.T.); -#680 = FACE_BOUND('',#681,.T.); -#681 = EDGE_LOOP('',(#682,#690,#691,#699)); -#682 = ORIENTED_EDGE('',*,*,#683,.F.); -#683 = EDGE_CURVE('',#156,#684,#686,.T.); -#684 = VERTEX_POINT('',#685); -#685 = CARTESIAN_POINT('',(32.703857168398,3.2,-60.78483712899)); -#686 = LINE('',#687,#688); -#687 = CARTESIAN_POINT('',(32.703857168398,3.,-60.78483712899)); -#688 = VECTOR('',#689,1.); -#689 = DIRECTION('',(0.,1.,0.)); -#690 = ORIENTED_EDGE('',*,*,#155,.T.); -#691 = ORIENTED_EDGE('',*,*,#692,.F.); -#692 = EDGE_CURVE('',#693,#158,#695,.T.); -#693 = VERTEX_POINT('',#694); -#694 = CARTESIAN_POINT('',(26.938753236523,3.2,-55.20570756731)); -#695 = LINE('',#696,#697); -#696 = CARTESIAN_POINT('',(26.938753236523,3.,-55.20570756731)); -#697 = VECTOR('',#698,1.); -#698 = DIRECTION('',(0.,-1.,0.)); -#699 = ORIENTED_EDGE('',*,*,#700,.F.); -#700 = EDGE_CURVE('',#684,#693,#701,.T.); -#701 = LINE('',#702,#703); -#702 = CARTESIAN_POINT('',(16.008242280412,3.2,-44.62779994931)); -#703 = VECTOR('',#704,1.); -#704 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#705 = PLANE('',#706); -#706 = AXIS2_PLACEMENT_3D('',#707,#708,#709); -#707 = CARTESIAN_POINT('',(29.704873980143,3.,-57.88259703786)); -#708 = DIRECTION('',(-0.695421216677,0.,-0.718602345805)); -#709 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#710 = ADVANCED_FACE('',(#711),#729,.T.); -#711 = FACE_BOUND('',#712,.T.); -#712 = EDGE_LOOP('',(#713,#721,#722,#723)); -#713 = ORIENTED_EDGE('',*,*,#714,.F.); -#714 = EDGE_CURVE('',#274,#715,#717,.T.); -#715 = VERTEX_POINT('',#716); -#716 = CARTESIAN_POINT('',(26.715163243538,3.2,-66.97315781796)); -#717 = LINE('',#718,#719); -#718 = CARTESIAN_POINT('',(26.715163243538,3.,-66.97315781796)); -#719 = VECTOR('',#720,1.); -#720 = DIRECTION('',(0.,1.,0.)); -#721 = ORIENTED_EDGE('',*,*,#281,.T.); -#722 = ORIENTED_EDGE('',*,*,#683,.T.); -#723 = ORIENTED_EDGE('',*,*,#724,.F.); -#724 = EDGE_CURVE('',#715,#684,#725,.T.); -#725 = LINE('',#726,#727); -#726 = CARTESIAN_POINT('',(30.25240665457,3.2,-63.31800414721)); -#727 = VECTOR('',#728,1.); -#728 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#729 = PLANE('',#730); -#730 = AXIS2_PLACEMENT_3D('',#731,#732,#733); -#731 = CARTESIAN_POINT('',(29.709510205968,3.,-63.87899747347)); -#732 = DIRECTION('',(-0.718602345805,0.,0.695421216677)); -#733 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#734 = ADVANCED_FACE('',(#735),#753,.T.); -#735 = FACE_BOUND('',#736,.T.); -#736 = EDGE_LOOP('',(#737,#745,#746,#747)); -#737 = ORIENTED_EDGE('',*,*,#738,.F.); -#738 = EDGE_CURVE('',#693,#739,#741,.T.); -#739 = VERTEX_POINT('',#740); -#740 = CARTESIAN_POINT('',(42.298608189024,3.2,-7.015765476549)); -#741 = LINE('',#742,#743); -#742 = CARTESIAN_POINT('',(32.699020781567,3.2,-37.13346923684)); -#743 = VECTOR('',#744,1.); -#744 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#745 = ORIENTED_EDGE('',*,*,#692,.T.); -#746 = ORIENTED_EDGE('',*,*,#165,.T.); -#747 = ORIENTED_EDGE('',*,*,#748,.F.); -#748 = EDGE_CURVE('',#739,#166,#749,.T.); -#749 = LINE('',#750,#751); -#750 = CARTESIAN_POINT('',(42.298608189024,3.,-7.015765476549)); -#751 = VECTOR('',#752,1.); -#752 = DIRECTION('',(0.,-1.,0.)); -#753 = PLANE('',#754); -#754 = AXIS2_PLACEMENT_3D('',#755,#756,#757); -#755 = CARTESIAN_POINT('',(34.581352051556,3.,-31.22785130119)); -#756 = DIRECTION('',(-0.952773183837,0.,0.30368282823)); -#757 = DIRECTION('',(0.30368282823,0.,0.952773183837)); -#758 = ADVANCED_FACE('',(#759),#777,.T.); -#759 = FACE_BOUND('',#760,.T.); -#760 = EDGE_LOOP('',(#761,#769,#775,#776)); -#761 = ORIENTED_EDGE('',*,*,#762,.F.); -#762 = EDGE_CURVE('',#763,#715,#765,.T.); -#763 = VERTEX_POINT('',#764); -#764 = CARTESIAN_POINT('',(20.532019001374,3.2,-60.98947335481)); -#765 = LINE('',#766,#767); -#766 = CARTESIAN_POINT('',(9.922784884512,3.2,-50.72247862452)); -#767 = VECTOR('',#768,1.); -#768 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#769 = ORIENTED_EDGE('',*,*,#770,.T.); -#770 = EDGE_CURVE('',#763,#266,#771,.T.); -#771 = LINE('',#772,#773); -#772 = CARTESIAN_POINT('',(20.532019001374,3.,-60.98947335481)); -#773 = VECTOR('',#774,1.); -#774 = DIRECTION('',(0.,-1.,0.)); -#775 = ORIENTED_EDGE('',*,*,#273,.T.); -#776 = ORIENTED_EDGE('',*,*,#714,.T.); -#777 = PLANE('',#778); -#778 = AXIS2_PLACEMENT_3D('',#779,#780,#781); -#779 = CARTESIAN_POINT('',(23.522653113203,3.,-63.8836336993)); -#780 = DIRECTION('',(0.695421216677,0.,0.718602345805)); -#781 = DIRECTION('',(0.718602345805,0.,-0.695421216677)); -#782 = ADVANCED_FACE('',(#783),#801,.T.); -#783 = FACE_BOUND('',#784,.T.); -#784 = EDGE_LOOP('',(#785,#786,#787,#795)); -#785 = ORIENTED_EDGE('',*,*,#748,.T.); -#786 = ORIENTED_EDGE('',*,*,#173,.T.); -#787 = ORIENTED_EDGE('',*,*,#788,.F.); -#788 = EDGE_CURVE('',#789,#174,#791,.T.); -#789 = VERTEX_POINT('',#790); -#790 = CARTESIAN_POINT('',(35.082842712475,3.2,0.2)); -#791 = LINE('',#792,#793); -#792 = CARTESIAN_POINT('',(35.082842712475,3.,0.2)); -#793 = VECTOR('',#794,1.); -#794 = DIRECTION('',(0.,-1.,0.)); -#795 = ORIENTED_EDGE('',*,*,#796,.F.); -#796 = EDGE_CURVE('',#739,#789,#797,.T.); -#797 = LINE('',#798,#799); -#798 = CARTESIAN_POINT('',(36.596246576251,3.2,-1.313403863776)); -#799 = VECTOR('',#800,1.); -#800 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#801 = PLANE('',#802); -#802 = AXIS2_PLACEMENT_3D('',#803,#804,#805); -#803 = CARTESIAN_POINT('',(38.67695526217,3.,-3.394112549695)); -#804 = DIRECTION('',(-0.707106781187,0.,-0.707106781187)); -#805 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#806 = ADVANCED_FACE('',(#807),#825,.T.); -#807 = FACE_BOUND('',#808,.T.); -#808 = EDGE_LOOP('',(#809,#817,#818,#819)); -#809 = ORIENTED_EDGE('',*,*,#810,.F.); -#810 = EDGE_CURVE('',#258,#811,#813,.T.); -#811 = VERTEX_POINT('',#812); -#812 = CARTESIAN_POINT('',(-20.53201900137,3.2,-60.98947335481)); -#813 = LINE('',#814,#815); -#814 = CARTESIAN_POINT('',(-20.53201900137,3.,-60.98947335481)); -#815 = VECTOR('',#816,1.); -#816 = DIRECTION('',(0.,1.,0.)); -#817 = ORIENTED_EDGE('',*,*,#265,.T.); -#818 = ORIENTED_EDGE('',*,*,#770,.F.); -#819 = ORIENTED_EDGE('',*,*,#820,.F.); -#820 = EDGE_CURVE('',#811,#763,#821,.T.); -#821 = LINE('',#822,#823); -#822 = CARTESIAN_POINT('',(5.354765181569,3.2,-60.98947335481)); -#823 = VECTOR('',#824,1.); -#824 = DIRECTION('',(1.,0.,0.)); -#825 = PLANE('',#826); -#826 = AXIS2_PLACEMENT_3D('',#827,#828,#829); -#827 = CARTESIAN_POINT('',(10.306473847682,3.,-60.98947335481)); -#828 = DIRECTION('',(0.,0.,1.)); -#829 = DIRECTION('',(0.,-1.,0.)); -#830 = ADVANCED_FACE('',(#831),#849,.F.); -#831 = FACE_BOUND('',#832,.F.); -#832 = EDGE_LOOP('',(#833,#834,#842,#848)); -#833 = ORIENTED_EDGE('',*,*,#788,.F.); -#834 = ORIENTED_EDGE('',*,*,#835,.F.); -#835 = EDGE_CURVE('',#836,#789,#838,.T.); -#836 = VERTEX_POINT('',#837); -#837 = CARTESIAN_POINT('',(-32.57517518159,3.2,0.2)); -#838 = LINE('',#839,#840); -#839 = CARTESIAN_POINT('',(-7.942265537672,3.2,0.2)); -#840 = VECTOR('',#841,1.); -#841 = DIRECTION('',(1.,0.,0.)); -#842 = ORIENTED_EDGE('',*,*,#843,.T.); -#843 = EDGE_CURVE('',#836,#182,#844,.T.); -#844 = LINE('',#845,#846); -#845 = CARTESIAN_POINT('',(-32.57517518159,3.,0.2)); -#846 = VECTOR('',#847,1.); -#847 = DIRECTION('',(0.,-1.,0.)); -#848 = ORIENTED_EDGE('',*,*,#181,.T.); -#849 = PLANE('',#850); -#850 = AXIS2_PLACEMENT_3D('',#851,#852,#853); -#851 = CARTESIAN_POINT('',(-16.28758759079,3.,0.2)); -#852 = DIRECTION('',(0.,0.,1.)); -#853 = DIRECTION('',(0.,-1.,0.)); -#854 = ADVANCED_FACE('',(#855),#873,.F.); -#855 = FACE_BOUND('',#856,.F.); -#856 = EDGE_LOOP('',(#857,#865,#871,#872)); -#857 = ORIENTED_EDGE('',*,*,#858,.F.); -#858 = EDGE_CURVE('',#859,#249,#861,.T.); -#859 = VERTEX_POINT('',#860); -#860 = CARTESIAN_POINT('',(-25.53052705686,3.2,-65.82673637491)); -#861 = LINE('',#862,#863); -#862 = CARTESIAN_POINT('',(-25.53052705686,3.,-65.82673637491)); -#863 = VECTOR('',#864,1.); -#864 = DIRECTION('',(0.,-1.,0.)); -#865 = ORIENTED_EDGE('',*,*,#866,.F.); -#866 = EDGE_CURVE('',#811,#859,#867,.T.); -#867 = LINE('',#868,#869); -#868 = CARTESIAN_POINT('',(-9.454421870603,3.2,-50.26922436104)); -#869 = VECTOR('',#870,1.); -#870 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#871 = ORIENTED_EDGE('',*,*,#810,.F.); -#872 = ORIENTED_EDGE('',*,*,#257,.T.); -#873 = PLANE('',#874); -#874 = AXIS2_PLACEMENT_3D('',#875,#876,#877); -#875 = CARTESIAN_POINT('',(-23.00219525444,3.,-63.37996509944)); -#876 = DIRECTION('',(0.695421216677,0.,-0.718602345805)); -#877 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#878 = ADVANCED_FACE('',(#879),#898,.F.); -#879 = FACE_BOUND('',#880,.F.); -#880 = EDGE_LOOP('',(#881,#882,#891,#897)); -#881 = ORIENTED_EDGE('',*,*,#843,.F.); -#882 = ORIENTED_EDGE('',*,*,#883,.T.); -#883 = EDGE_CURVE('',#836,#884,#886,.T.); -#884 = VERTEX_POINT('',#885); -#885 = CARTESIAN_POINT('',(-36.85603142851,3.2,-1.573188716044)); -#886 = CIRCLE('',#887,6.054044962965); -#887 = AXIS2_PLACEMENT_3D('',#888,#889,#890); -#888 = CARTESIAN_POINT('',(-32.57517518159,3.2,-5.854044962965)); -#889 = DIRECTION('',(0.,-1.,0.)); -#890 = DIRECTION('',(-1.,0.,0.)); -#891 = ORIENTED_EDGE('',*,*,#892,.T.); -#892 = EDGE_CURVE('',#884,#190,#893,.T.); -#893 = LINE('',#894,#895); -#894 = CARTESIAN_POINT('',(-36.85603142851,3.,-1.573188716044)); -#895 = VECTOR('',#896,1.); -#896 = DIRECTION('',(0.,-1.,0.)); -#897 = ORIENTED_EDGE('',*,*,#189,.F.); -#898 = CYLINDRICAL_SURFACE('',#899,6.054044962965); -#899 = AXIS2_PLACEMENT_3D('',#900,#901,#902); -#900 = CARTESIAN_POINT('',(-32.57517518159,3.,-5.854044962965)); -#901 = DIRECTION('',(0.,-1.,0.)); -#902 = DIRECTION('',(-1.,0.,0.)); -#903 = ADVANCED_FACE('',(#904),#923,.F.); -#904 = FACE_BOUND('',#905,.F.); -#905 = EDGE_LOOP('',(#906,#914,#921,#922)); -#906 = ORIENTED_EDGE('',*,*,#907,.F.); -#907 = EDGE_CURVE('',#908,#241,#910,.T.); -#908 = VERTEX_POINT('',#909); -#909 = CARTESIAN_POINT('',(-27.86158468659,3.2,-65.78852163128)); -#910 = LINE('',#911,#912); -#911 = CARTESIAN_POINT('',(-27.86158468659,3.,-65.78852163128)); -#912 = VECTOR('',#913,1.); -#913 = DIRECTION('',(0.,-1.,0.)); -#914 = ORIENTED_EDGE('',*,*,#915,.T.); -#915 = EDGE_CURVE('',#908,#859,#916,.T.); -#916 = CIRCLE('',#917,1.648528137424); -#917 = AXIS2_PLACEMENT_3D('',#918,#919,#920); -#918 = CARTESIAN_POINT('',(-26.67694849991,3.2,-64.64210018823)); -#919 = DIRECTION('',(0.,-1.,0.)); -#920 = DIRECTION('',(-1.,0.,0.)); -#921 = ORIENTED_EDGE('',*,*,#858,.T.); -#922 = ORIENTED_EDGE('',*,*,#248,.F.); -#923 = CYLINDRICAL_SURFACE('',#924,1.648528137424); -#924 = AXIS2_PLACEMENT_3D('',#925,#926,#927); -#925 = CARTESIAN_POINT('',(-26.67694849991,3.,-64.64210018823)); -#926 = DIRECTION('',(0.,-1.,0.)); -#927 = DIRECTION('',(-1.,0.,0.)); -#928 = ADVANCED_FACE('',(#929),#947,.F.); -#929 = FACE_BOUND('',#930,.F.); -#930 = EDGE_LOOP('',(#931,#932,#940,#946)); -#931 = ORIENTED_EDGE('',*,*,#892,.F.); -#932 = ORIENTED_EDGE('',*,*,#933,.F.); -#933 = EDGE_CURVE('',#934,#884,#936,.T.); -#934 = VERTEX_POINT('',#935); -#935 = CARTESIAN_POINT('',(-39.69176606491,3.2,-4.408923352436)); -#936 = LINE('',#937,#938); -#937 = CARTESIAN_POINT('',(-36.19319006079,3.2,-0.910347348321)); -#938 = VECTOR('',#939,1.); -#939 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#940 = ORIENTED_EDGE('',*,*,#941,.T.); -#941 = EDGE_CURVE('',#934,#199,#942,.T.); -#942 = LINE('',#943,#944); -#943 = CARTESIAN_POINT('',(-39.69176606491,3.,-4.408923352436)); -#944 = VECTOR('',#945,1.); -#945 = DIRECTION('',(0.,-1.,0.)); -#946 = ORIENTED_EDGE('',*,*,#198,.T.); -#947 = PLANE('',#948); -#948 = AXIS2_PLACEMENT_3D('',#949,#950,#951); -#949 = CARTESIAN_POINT('',(-38.27389874671,3.,-2.99105603424)); -#950 = DIRECTION('',(-0.707106781187,0.,0.707106781187)); -#951 = DIRECTION('',(0.707106781187,0.,0.707106781187)); -#952 = ADVANCED_FACE('',(#953),#971,.F.); -#953 = FACE_BOUND('',#954,.F.); -#954 = EDGE_LOOP('',(#955,#963,#969,#970)); -#955 = ORIENTED_EDGE('',*,*,#956,.F.); -#956 = EDGE_CURVE('',#957,#232,#959,.T.); -#957 = VERTEX_POINT('',#958); -#958 = CARTESIAN_POINT('',(-29.08766684168,3.2,-64.52156932717)); -#959 = LINE('',#960,#961); -#960 = CARTESIAN_POINT('',(-29.08766684168,3.,-64.52156932717)); -#961 = VECTOR('',#962,1.); -#962 = DIRECTION('',(0.,-1.,0.)); -#963 = ORIENTED_EDGE('',*,*,#964,.F.); -#964 = EDGE_CURVE('',#908,#957,#965,.T.); -#965 = LINE('',#966,#967); -#966 = CARTESIAN_POINT('',(-29.44004200272,3.2,-64.15744811364)); -#967 = VECTOR('',#968,1.); -#968 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#969 = ORIENTED_EDGE('',*,*,#907,.T.); -#970 = ORIENTED_EDGE('',*,*,#240,.T.); -#971 = PLANE('',#972); -#972 = AXIS2_PLACEMENT_3D('',#973,#974,#975); -#973 = CARTESIAN_POINT('',(-28.47462576413,3.,-65.15504547923)); -#974 = DIRECTION('',(-0.718602345805,0.,-0.695421216677)); -#975 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#976 = ADVANCED_FACE('',(#977),#996,.F.); -#977 = FACE_BOUND('',#978,.F.); -#978 = EDGE_LOOP('',(#979,#980,#989,#995)); -#979 = ORIENTED_EDGE('',*,*,#941,.F.); -#980 = ORIENTED_EDGE('',*,*,#981,.T.); -#981 = EDGE_CURVE('',#934,#982,#984,.T.); -#982 = VERTEX_POINT('',#983); -#983 = CARTESIAN_POINT('',(-41.17904151244,3.2,-10.52828909594)); -#984 = CIRCLE('',#985,6.054044962965); -#985 = AXIS2_PLACEMENT_3D('',#986,#987,#988); -#986 = CARTESIAN_POINT('',(-35.41090981799,3.2,-8.689779599357)); -#987 = DIRECTION('',(0.,-1.,0.)); -#988 = DIRECTION('',(-1.,0.,0.)); -#989 = ORIENTED_EDGE('',*,*,#990,.T.); -#990 = EDGE_CURVE('',#982,#207,#991,.T.); -#991 = LINE('',#992,#993); -#992 = CARTESIAN_POINT('',(-41.17904151244,3.,-10.52828909594)); -#993 = VECTOR('',#994,1.); -#994 = DIRECTION('',(0.,-1.,0.)); -#995 = ORIENTED_EDGE('',*,*,#206,.F.); -#996 = CYLINDRICAL_SURFACE('',#997,6.054044962965); -#997 = AXIS2_PLACEMENT_3D('',#998,#999,#1000); -#998 = CARTESIAN_POINT('',(-35.41090981799,3.,-8.689779599357)); -#999 = DIRECTION('',(0.,-1.,0.)); -#1000 = DIRECTION('',(-1.,0.,0.)); -#1001 = ADVANCED_FACE('',(#1002),#1021,.F.); -#1002 = FACE_BOUND('',#1003,.F.); -#1003 = EDGE_LOOP('',(#1004,#1012,#1019,#1020)); -#1004 = ORIENTED_EDGE('',*,*,#1005,.F.); -#1005 = EDGE_CURVE('',#1006,#224,#1008,.T.); -#1006 = VERTEX_POINT('',#1007); -#1007 = CARTESIAN_POINT('',(-28.96712497021,3.2,-57.16864680227)); -#1008 = LINE('',#1009,#1010); -#1009 = CARTESIAN_POINT('',(-28.96712497021,3.,-57.16864680227)); -#1010 = VECTOR('',#1011,1.); -#1011 = DIRECTION('',(0.,-1.,0.)); -#1012 = ORIENTED_EDGE('',*,*,#1013,.T.); -#1013 = EDGE_CURVE('',#1006,#957,#1014,.T.); -#1014 = CIRCLE('',#1015,5.2); -#1015 = AXIS2_PLACEMENT_3D('',#1016,#1017,#1018); -#1016 = CARTESIAN_POINT('',(-25.35093464349,3.2,-60.90537900045)); -#1017 = DIRECTION('',(0.,-1.,0.)); -#1018 = DIRECTION('',(-1.,0.,0.)); -#1019 = ORIENTED_EDGE('',*,*,#956,.T.); -#1020 = ORIENTED_EDGE('',*,*,#231,.F.); -#1021 = CYLINDRICAL_SURFACE('',#1022,5.2); -#1022 = AXIS2_PLACEMENT_3D('',#1023,#1024,#1025); -#1023 = CARTESIAN_POINT('',(-25.35093464349,3.,-60.90537900045)); -#1024 = DIRECTION('',(0.,-1.,0.)); -#1025 = DIRECTION('',(-1.,0.,0.)); -#1026 = ADVANCED_FACE('',(#1027),#1045,.F.); -#1027 = FACE_BOUND('',#1028,.F.); -#1028 = EDGE_LOOP('',(#1029,#1030,#1038,#1044)); -#1029 = ORIENTED_EDGE('',*,*,#990,.F.); -#1030 = ORIENTED_EDGE('',*,*,#1031,.F.); -#1031 = EDGE_CURVE('',#1032,#982,#1034,.T.); -#1032 = VERTEX_POINT('',#1033); -#1033 = CARTESIAN_POINT('',(-26.93875323652,3.2,-55.20570756731)); -#1034 = LINE('',#1035,#1036); -#1035 = CARTESIAN_POINT('',(-32.39120436163,3.2,-38.09921113329)); -#1036 = VECTOR('',#1037,1.); -#1037 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#1038 = ORIENTED_EDGE('',*,*,#1039,.T.); -#1039 = EDGE_CURVE('',#1032,#216,#1040,.T.); -#1040 = LINE('',#1041,#1042); -#1041 = CARTESIAN_POINT('',(-26.93875323652,3.,-55.20570756731)); -#1042 = VECTOR('',#1043,1.); -#1043 = DIRECTION('',(0.,-1.,0.)); -#1044 = ORIENTED_EDGE('',*,*,#215,.T.); -#1045 = PLANE('',#1046); -#1046 = AXIS2_PLACEMENT_3D('',#1047,#1048,#1049); -#1047 = CARTESIAN_POINT('',(-34.04006158346,3.,-32.92609366041)); -#1048 = DIRECTION('',(-0.952773183837,0.,-0.30368282823)); -#1049 = DIRECTION('',(-0.30368282823,0.,0.952773183837)); -#1050 = ADVANCED_FACE('',(#1051),#1062,.F.); -#1051 = FACE_BOUND('',#1052,.F.); -#1052 = EDGE_LOOP('',(#1053,#1054,#1060,#1061)); -#1053 = ORIENTED_EDGE('',*,*,#1039,.F.); -#1054 = ORIENTED_EDGE('',*,*,#1055,.F.); -#1055 = EDGE_CURVE('',#1006,#1032,#1056,.T.); -#1056 = LINE('',#1057,#1058); -#1057 = CARTESIAN_POINT('',(-14.90185526362,3.2,-43.55710346492)); -#1058 = VECTOR('',#1059,1.); -#1059 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#1060 = ORIENTED_EDGE('',*,*,#1005,.T.); -#1061 = ORIENTED_EDGE('',*,*,#223,.T.); -#1062 = PLANE('',#1063); -#1063 = AXIS2_PLACEMENT_3D('',#1064,#1065,#1066); -#1064 = CARTESIAN_POINT('',(-27.90836811563,3.,-56.14404399617)); -#1065 = DIRECTION('',(-0.695421216677,0.,0.718602345805)); -#1066 = DIRECTION('',(0.718602345805,0.,0.695421216677)); -#1067 = ADVANCED_FACE('',(#1068),#1086,.T.); -#1068 = FACE_BOUND('',#1069,.T.); -#1069 = EDGE_LOOP('',(#1070,#1071,#1072,#1073,#1074,#1075,#1076,#1077, - #1078,#1079,#1080,#1081,#1082,#1083,#1084,#1085)); -#1070 = ORIENTED_EDGE('',*,*,#304,.F.); -#1071 = ORIENTED_EDGE('',*,*,#668,.F.); -#1072 = ORIENTED_EDGE('',*,*,#651,.F.); -#1073 = ORIENTED_EDGE('',*,*,#627,.F.); -#1074 = ORIENTED_EDGE('',*,*,#603,.F.); -#1075 = ORIENTED_EDGE('',*,*,#572,.T.); -#1076 = ORIENTED_EDGE('',*,*,#554,.F.); -#1077 = ORIENTED_EDGE('',*,*,#523,.T.); -#1078 = ORIENTED_EDGE('',*,*,#505,.F.); -#1079 = ORIENTED_EDGE('',*,*,#474,.T.); -#1080 = ORIENTED_EDGE('',*,*,#450,.T.); -#1081 = ORIENTED_EDGE('',*,*,#432,.F.); -#1082 = ORIENTED_EDGE('',*,*,#401,.T.); -#1083 = ORIENTED_EDGE('',*,*,#383,.F.); -#1084 = ORIENTED_EDGE('',*,*,#352,.T.); -#1085 = ORIENTED_EDGE('',*,*,#335,.F.); -#1086 = PLANE('',#1087); -#1087 = AXIS2_PLACEMENT_3D('',#1088,#1089,#1090); -#1088 = CARTESIAN_POINT('',(-45.46495478095,20.8572529153, - -70.97315781796)); -#1089 = DIRECTION('',(0.,1.,0.)); -#1090 = DIRECTION('',(0.,0.,1.)); -#1091 = ADVANCED_FACE('',(#1092,#1142,#1153,#1171,#1205),#1216,.F.); -#1092 = FACE_BOUND('',#1093,.F.); -#1093 = EDGE_LOOP('',(#1094,#1104,#1112,#1120,#1128,#1136)); -#1094 = ORIENTED_EDGE('',*,*,#1095,.F.); -#1095 = EDGE_CURVE('',#1096,#1098,#1100,.T.); -#1096 = VERTEX_POINT('',#1097); -#1097 = CARTESIAN_POINT('',(16.626582997737,3.2,-8.940188245231)); -#1098 = VERTEX_POINT('',#1099); -#1099 = CARTESIAN_POINT('',(4.383041634064E-04,3.2,-8.903751615529)); -#1100 = LINE('',#1101,#1102); -#1101 = CARTESIAN_POINT('',(4.347099726942,3.2,-8.913277437397)); -#1102 = VECTOR('',#1103,1.); -#1103 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1104 = ORIENTED_EDGE('',*,*,#1105,.F.); -#1105 = EDGE_CURVE('',#1106,#1096,#1108,.T.); -#1106 = VERTEX_POINT('',#1107); -#1107 = CARTESIAN_POINT('',(19.029295926024,3.2,-17.63009960955)); -#1108 = LINE('',#1109,#1110); -#1109 = CARTESIAN_POINT('',(19.849519003668,3.2,-20.59660707692)); -#1110 = VECTOR('',#1111,1.); -#1111 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1112 = ORIENTED_EDGE('',*,*,#1113,.F.); -#1113 = EDGE_CURVE('',#1114,#1106,#1116,.T.); -#1114 = VERTEX_POINT('',#1115); -#1115 = CARTESIAN_POINT('',(22.059435554995,3.2,-3.734519760785)); -#1116 = LINE('',#1117,#1118); -#1117 = CARTESIAN_POINT('',(17.698510515043,3.2,-23.73280021221)); -#1118 = VECTOR('',#1119,1.); -#1119 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1120 = ORIENTED_EDGE('',*,*,#1121,.F.); -#1121 = EDGE_CURVE('',#1122,#1114,#1124,.T.); -#1122 = VERTEX_POINT('',#1123); -#1123 = CARTESIAN_POINT('',(-21.72552223146,3.2,-3.734519760785)); -#1124 = LINE('',#1125,#1126); -#1125 = CARTESIAN_POINT('',(0.297084840953,3.2,-3.734519760785)); -#1126 = VECTOR('',#1127,1.); -#1127 = DIRECTION('',(1.,0.,0.)); -#1128 = ORIENTED_EDGE('',*,*,#1129,.F.); -#1129 = EDGE_CURVE('',#1130,#1122,#1132,.T.); -#1130 = VERTEX_POINT('',#1131); -#1131 = CARTESIAN_POINT('',(-21.72552223146,3.2,-8.903751135252)); -#1132 = LINE('',#1133,#1134); -#1133 = CARTESIAN_POINT('',(-21.72552223146,3.2,-19.83215600037)); -#1134 = VECTOR('',#1135,1.); -#1135 = DIRECTION('',(0.,0.,1.)); -#1136 = ORIENTED_EDGE('',*,*,#1137,.F.); -#1137 = EDGE_CURVE('',#1098,#1130,#1138,.T.); -#1138 = LINE('',#1139,#1140); -#1139 = CARTESIAN_POINT('',(-5.279852300138,3.2,-8.903751135252)); -#1140 = VECTOR('',#1141,1.); -#1141 = DIRECTION('',(-1.,0.,0.)); -#1142 = FACE_BOUND('',#1143,.F.); -#1143 = EDGE_LOOP('',(#1144)); -#1144 = ORIENTED_EDGE('',*,*,#1145,.F.); -#1145 = EDGE_CURVE('',#1146,#1146,#1148,.T.); -#1146 = VERTEX_POINT('',#1147); -#1147 = CARTESIAN_POINT('',(21.163799345768,3.2,-48.00951684793)); -#1148 = CIRCLE('',#1149,4.735522705283); -#1149 = AXIS2_PLACEMENT_3D('',#1150,#1151,#1152); -#1150 = CARTESIAN_POINT('',(16.428276640485,3.2,-48.00951684793)); -#1151 = DIRECTION('',(-0.,1.,0.)); -#1152 = DIRECTION('',(1.,0.,0.)); -#1153 = FACE_BOUND('',#1154,.F.); -#1154 = EDGE_LOOP('',(#1155,#1156,#1157,#1158,#1159,#1160,#1161,#1162, - #1163,#1164,#1165,#1166,#1167,#1168,#1169,#1170)); -#1155 = ORIENTED_EDGE('',*,*,#1031,.T.); -#1156 = ORIENTED_EDGE('',*,*,#981,.F.); -#1157 = ORIENTED_EDGE('',*,*,#933,.T.); -#1158 = ORIENTED_EDGE('',*,*,#883,.F.); -#1159 = ORIENTED_EDGE('',*,*,#835,.T.); -#1160 = ORIENTED_EDGE('',*,*,#796,.F.); -#1161 = ORIENTED_EDGE('',*,*,#738,.F.); -#1162 = ORIENTED_EDGE('',*,*,#700,.F.); -#1163 = ORIENTED_EDGE('',*,*,#724,.F.); -#1164 = ORIENTED_EDGE('',*,*,#762,.F.); -#1165 = ORIENTED_EDGE('',*,*,#820,.F.); -#1166 = ORIENTED_EDGE('',*,*,#866,.T.); -#1167 = ORIENTED_EDGE('',*,*,#915,.F.); -#1168 = ORIENTED_EDGE('',*,*,#964,.T.); -#1169 = ORIENTED_EDGE('',*,*,#1013,.F.); -#1170 = ORIENTED_EDGE('',*,*,#1055,.T.); -#1171 = FACE_BOUND('',#1172,.F.); -#1172 = EDGE_LOOP('',(#1173,#1183,#1191,#1199)); -#1173 = ORIENTED_EDGE('',*,*,#1174,.F.); -#1174 = EDGE_CURVE('',#1175,#1177,#1179,.T.); -#1175 = VERTEX_POINT('',#1176); -#1176 = CARTESIAN_POINT('',(5.809375885494,3.2,-13.06417917474)); -#1177 = VERTEX_POINT('',#1178); -#1178 = CARTESIAN_POINT('',(2.688069798796,3.2,-49.64588621989)); -#1179 = LINE('',#1180,#1181); -#1180 = CARTESIAN_POINT('',(4.914157977861,3.2,-23.55613296875)); -#1181 = VECTOR('',#1182,1.); -#1182 = DIRECTION('',(-8.501532861638E-02,0.,-0.996379643459)); -#1183 = ORIENTED_EDGE('',*,*,#1184,.F.); -#1184 = EDGE_CURVE('',#1185,#1175,#1187,.T.); -#1185 = VERTEX_POINT('',#1186); -#1186 = CARTESIAN_POINT('',(-5.809375885494,3.2,-13.06417917474)); -#1187 = LINE('',#1188,#1189); -#1188 = CARTESIAN_POINT('',(1.615747408047,3.2,-13.06417917474)); -#1189 = VECTOR('',#1190,1.); -#1190 = DIRECTION('',(1.,0.,-3.066574716487E-16)); -#1191 = ORIENTED_EDGE('',*,*,#1192,.F.); -#1192 = EDGE_CURVE('',#1193,#1185,#1195,.T.); -#1193 = VERTEX_POINT('',#1194); -#1194 = CARTESIAN_POINT('',(-2.688069798796,3.2,-49.64588621989)); -#1195 = LINE('',#1196,#1197); -#1196 = CARTESIAN_POINT('',(-4.890802006217,3.2,-23.82986495424)); -#1197 = VECTOR('',#1198,1.); -#1198 = DIRECTION('',(-8.501532861638E-02,0.,0.996379643459)); -#1199 = ORIENTED_EDGE('',*,*,#1200,.F.); -#1200 = EDGE_CURVE('',#1177,#1193,#1201,.T.); -#1201 = LINE('',#1202,#1203); -#1202 = CARTESIAN_POINT('',(1.615747408047,3.2,-49.64588621989)); -#1203 = VECTOR('',#1204,1.); -#1204 = DIRECTION('',(-1.,0.,0.)); -#1205 = FACE_BOUND('',#1206,.F.); -#1206 = EDGE_LOOP('',(#1207)); -#1207 = ORIENTED_EDGE('',*,*,#1208,.F.); -#1208 = EDGE_CURVE('',#1209,#1209,#1211,.T.); -#1209 = VERTEX_POINT('',#1210); -#1210 = CARTESIAN_POINT('',(-11.6927539352,3.2,-48.00951684793)); -#1211 = CIRCLE('',#1212,4.735522705283); -#1212 = AXIS2_PLACEMENT_3D('',#1213,#1214,#1215); -#1213 = CARTESIAN_POINT('',(-16.42827664048,3.2,-48.00951684793)); -#1214 = DIRECTION('',(-0.,1.,0.)); -#1215 = DIRECTION('',(1.,0.,0.)); -#1216 = PLANE('',#1217); -#1217 = AXIS2_PLACEMENT_3D('',#1218,#1219,#1220); -#1218 = CARTESIAN_POINT('',(0.403056515455,3.2,-33.34517655273)); -#1219 = DIRECTION('',(0.,1.,0.)); -#1220 = DIRECTION('',(1.,0.,0.)); -#1221 = ADVANCED_FACE('',(#1222),#1247,.T.); -#1222 = FACE_BOUND('',#1223,.T.); -#1223 = EDGE_LOOP('',(#1224,#1232,#1240,#1246)); -#1224 = ORIENTED_EDGE('',*,*,#1225,.F.); -#1225 = EDGE_CURVE('',#1226,#1096,#1228,.T.); -#1226 = VERTEX_POINT('',#1227); -#1227 = CARTESIAN_POINT('',(16.626582997737,0.,-8.940188245231)); -#1228 = LINE('',#1229,#1230); -#1229 = CARTESIAN_POINT('',(16.626582997737,-22.,-8.940188245231)); -#1230 = VECTOR('',#1231,1.); -#1231 = DIRECTION('',(0.,1.,0.)); -#1232 = ORIENTED_EDGE('',*,*,#1233,.T.); -#1233 = EDGE_CURVE('',#1226,#1234,#1236,.T.); -#1234 = VERTEX_POINT('',#1235); -#1235 = CARTESIAN_POINT('',(-5.329070518201E-15,0.,-8.903751135252)); -#1236 = LINE('',#1237,#1238); -#1237 = CARTESIAN_POINT('',(-18.54556462154,1.7763568394E-15, - -8.863107566442)); -#1238 = VECTOR('',#1239,1.); -#1239 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1240 = ORIENTED_EDGE('',*,*,#1241,.T.); -#1241 = EDGE_CURVE('',#1234,#1098,#1242,.T.); -#1242 = LINE('',#1243,#1244); -#1243 = CARTESIAN_POINT('',(-5.329070518201E-15,-22.,-8.903751135252)); -#1244 = VECTOR('',#1245,1.); -#1245 = DIRECTION('',(0.,1.,0.)); -#1246 = ORIENTED_EDGE('',*,*,#1095,.F.); -#1247 = PLANE('',#1248); -#1248 = AXIS2_PLACEMENT_3D('',#1249,#1250,#1251); -#1249 = CARTESIAN_POINT('',(8.237581109188,-22.,-8.921803528809)); -#1250 = DIRECTION('',(-2.19152081707E-03,0.,-0.999997598615)); -#1251 = DIRECTION('',(-0.999997598615,0.,2.19152081707E-03)); -#1252 = ADVANCED_FACE('',(#1253),#1271,.T.); -#1253 = FACE_BOUND('',#1254,.T.); -#1254 = EDGE_LOOP('',(#1255,#1263,#1269,#1270)); -#1255 = ORIENTED_EDGE('',*,*,#1256,.F.); -#1256 = EDGE_CURVE('',#1257,#1106,#1259,.T.); -#1257 = VERTEX_POINT('',#1258); -#1258 = CARTESIAN_POINT('',(19.029295926024,0.,-17.63009960955)); -#1259 = LINE('',#1260,#1261); -#1260 = CARTESIAN_POINT('',(19.029295926024,-22.,-17.63009960955)); -#1261 = VECTOR('',#1262,1.); -#1262 = DIRECTION('',(0.,1.,0.)); -#1263 = ORIENTED_EDGE('',*,*,#1264,.T.); -#1264 = EDGE_CURVE('',#1257,#1226,#1265,.T.); -#1265 = LINE('',#1266,#1267); -#1266 = CARTESIAN_POINT('',(23.053273013696,0.,-32.18365022821)); -#1267 = VECTOR('',#1268,1.); -#1268 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1269 = ORIENTED_EDGE('',*,*,#1225,.T.); -#1270 = ORIENTED_EDGE('',*,*,#1105,.F.); -#1271 = PLANE('',#1272); -#1272 = AXIS2_PLACEMENT_3D('',#1273,#1274,#1275); -#1273 = CARTESIAN_POINT('',(17.956031892536,-22.,-13.7484168618)); -#1274 = DIRECTION('',(-0.963836182336,0.,-0.26649542889)); -#1275 = DIRECTION('',(-0.26649542889,0.,0.963836182336)); -#1276 = ADVANCED_FACE('',(#1277),#1295,.T.); -#1277 = FACE_BOUND('',#1278,.T.); -#1278 = EDGE_LOOP('',(#1279,#1287,#1288,#1289)); -#1279 = ORIENTED_EDGE('',*,*,#1280,.T.); -#1280 = EDGE_CURVE('',#1281,#1257,#1283,.T.); -#1281 = VERTEX_POINT('',#1282); -#1282 = CARTESIAN_POINT('',(22.059435554995,0.,-3.734519760785)); -#1283 = LINE('',#1284,#1285); -#1284 = CARTESIAN_POINT('',(12.741012548745,1.7763568394E-15, - -46.46683800444)); -#1285 = VECTOR('',#1286,1.); -#1286 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1287 = ORIENTED_EDGE('',*,*,#1256,.T.); -#1288 = ORIENTED_EDGE('',*,*,#1113,.F.); -#1289 = ORIENTED_EDGE('',*,*,#1290,.F.); -#1290 = EDGE_CURVE('',#1281,#1114,#1291,.T.); -#1291 = LINE('',#1292,#1293); -#1292 = CARTESIAN_POINT('',(22.059435554995,-22.,-3.734519760785)); -#1293 = VECTOR('',#1294,1.); -#1294 = DIRECTION('',(0.,1.,0.)); -#1295 = PLANE('',#1296); -#1296 = AXIS2_PLACEMENT_3D('',#1297,#1298,#1299); -#1297 = CARTESIAN_POINT('',(20.484588228021,-22.,-10.95643672209)); -#1298 = DIRECTION('',(0.977039526026,0.,-0.213058124893)); -#1299 = DIRECTION('',(-0.213058124893,0.,-0.977039526026)); -#1300 = ADVANCED_FACE('',(#1301),#1319,.T.); -#1301 = FACE_BOUND('',#1302,.T.); -#1302 = EDGE_LOOP('',(#1303,#1311,#1312,#1313)); -#1303 = ORIENTED_EDGE('',*,*,#1304,.T.); -#1304 = EDGE_CURVE('',#1305,#1281,#1307,.T.); -#1305 = VERTEX_POINT('',#1306); -#1306 = CARTESIAN_POINT('',(-21.72552223146,0.,-3.734519760785)); -#1307 = LINE('',#1308,#1309); -#1308 = CARTESIAN_POINT('',(-22.63692080725,0.,-3.734519760785)); -#1309 = VECTOR('',#1310,1.); -#1310 = DIRECTION('',(1.,0.,0.)); -#1311 = ORIENTED_EDGE('',*,*,#1290,.T.); -#1312 = ORIENTED_EDGE('',*,*,#1121,.F.); -#1313 = ORIENTED_EDGE('',*,*,#1314,.F.); -#1314 = EDGE_CURVE('',#1305,#1122,#1315,.T.); -#1315 = LINE('',#1316,#1317); -#1316 = CARTESIAN_POINT('',(-21.72552223146,-22.,-3.734519760785)); -#1317 = VECTOR('',#1318,1.); -#1318 = DIRECTION('',(0.,1.,0.)); -#1319 = PLANE('',#1320); -#1320 = AXIS2_PLACEMENT_3D('',#1321,#1322,#1323); -#1321 = CARTESIAN_POINT('',(0.19111316645,-22.,-3.734519760785)); -#1322 = DIRECTION('',(0.,0.,1.)); -#1323 = DIRECTION('',(0.,-1.,0.)); -#1324 = ADVANCED_FACE('',(#1325),#1343,.T.); -#1325 = FACE_BOUND('',#1326,.T.); -#1326 = EDGE_LOOP('',(#1327,#1335,#1336,#1337)); -#1327 = ORIENTED_EDGE('',*,*,#1328,.T.); -#1328 = EDGE_CURVE('',#1329,#1305,#1331,.T.); -#1329 = VERTEX_POINT('',#1330); -#1330 = CARTESIAN_POINT('',(-21.72552223146,0.,-8.903751135252)); -#1331 = LINE('',#1332,#1333); -#1332 = CARTESIAN_POINT('',(-21.72552223146,0.,-38.64614663299)); -#1333 = VECTOR('',#1334,1.); -#1334 = DIRECTION('',(0.,0.,1.)); -#1335 = ORIENTED_EDGE('',*,*,#1314,.T.); -#1336 = ORIENTED_EDGE('',*,*,#1129,.F.); -#1337 = ORIENTED_EDGE('',*,*,#1338,.F.); -#1338 = EDGE_CURVE('',#1329,#1130,#1339,.T.); -#1339 = LINE('',#1340,#1341); -#1340 = CARTESIAN_POINT('',(-21.72552223146,-22.,-8.903751135252)); -#1341 = VECTOR('',#1342,1.); -#1342 = DIRECTION('',(0.,1.,0.)); -#1343 = PLANE('',#1344); -#1344 = AXIS2_PLACEMENT_3D('',#1345,#1346,#1347); -#1345 = CARTESIAN_POINT('',(-21.72552223146,-22.,-6.319135448019)); -#1346 = DIRECTION('',(-1.,0.,0.)); -#1347 = DIRECTION('',(0.,1.,0.)); -#1348 = ADVANCED_FACE('',(#1349),#1360,.T.); -#1349 = FACE_BOUND('',#1350,.T.); -#1350 = EDGE_LOOP('',(#1351,#1357,#1358,#1359)); -#1351 = ORIENTED_EDGE('',*,*,#1352,.T.); -#1352 = EDGE_CURVE('',#1234,#1329,#1353,.T.); -#1353 = LINE('',#1354,#1355); -#1354 = CARTESIAN_POINT('',(-28.21385794834,0.,-8.903751135252)); -#1355 = VECTOR('',#1356,1.); -#1356 = DIRECTION('',(-1.,0.,0.)); -#1357 = ORIENTED_EDGE('',*,*,#1338,.T.); -#1358 = ORIENTED_EDGE('',*,*,#1137,.F.); -#1359 = ORIENTED_EDGE('',*,*,#1241,.F.); -#1360 = PLANE('',#1361); -#1361 = AXIS2_PLACEMENT_3D('',#1362,#1363,#1364); -#1362 = CARTESIAN_POINT('',(-10.96276111573,-22.,-8.903751135252)); -#1363 = DIRECTION('',(0.,0.,-1.)); -#1364 = DIRECTION('',(0.,1.,0.)); -#1365 = ADVANCED_FACE('',(#1366),#1385,.T.); -#1366 = FACE_BOUND('',#1367,.T.); -#1367 = EDGE_LOOP('',(#1368,#1377,#1383,#1384)); -#1368 = ORIENTED_EDGE('',*,*,#1369,.T.); -#1369 = EDGE_CURVE('',#1370,#1370,#1372,.T.); -#1370 = VERTEX_POINT('',#1371); -#1371 = CARTESIAN_POINT('',(21.163799345768,0.,-48.00951684793)); -#1372 = CIRCLE('',#1373,4.735522705283); -#1373 = AXIS2_PLACEMENT_3D('',#1374,#1375,#1376); -#1374 = CARTESIAN_POINT('',(16.428276640485,0.,-48.00951684793)); -#1375 = DIRECTION('',(-0.,1.,0.)); -#1376 = DIRECTION('',(1.,0.,0.)); -#1377 = ORIENTED_EDGE('',*,*,#1378,.T.); -#1378 = EDGE_CURVE('',#1370,#1146,#1379,.T.); -#1379 = LINE('',#1380,#1381); -#1380 = CARTESIAN_POINT('',(21.163799345768,-22.,-48.00951684793)); -#1381 = VECTOR('',#1382,1.); -#1382 = DIRECTION('',(0.,1.,0.)); -#1383 = ORIENTED_EDGE('',*,*,#1145,.F.); -#1384 = ORIENTED_EDGE('',*,*,#1378,.F.); -#1385 = CYLINDRICAL_SURFACE('',#1386,4.735522705283); -#1386 = AXIS2_PLACEMENT_3D('',#1387,#1388,#1389); -#1387 = CARTESIAN_POINT('',(16.428276640485,-22.,-48.00951684793)); -#1388 = DIRECTION('',(0.,1.,0.)); -#1389 = DIRECTION('',(1.,0.,0.)); -#1390 = ADVANCED_FACE('',(#1391),#1416,.F.); -#1391 = FACE_BOUND('',#1392,.F.); -#1392 = EDGE_LOOP('',(#1393,#1403,#1409,#1410)); -#1393 = ORIENTED_EDGE('',*,*,#1394,.T.); -#1394 = EDGE_CURVE('',#1395,#1397,#1399,.T.); -#1395 = VERTEX_POINT('',#1396); -#1396 = CARTESIAN_POINT('',(1.480297366167E-15,11.242400581089, - -46.71869179633)); -#1397 = VERTEX_POINT('',#1398); -#1398 = CARTESIAN_POINT('',(3.256654205567E-15,17.8572529153, - -18.39898295202)); -#1399 = LINE('',#1400,#1401); -#1400 = CARTESIAN_POINT('',(2.6645352591E-15,18.133069549222, - -17.21814831317)); -#1401 = VECTOR('',#1402,1.); -#1402 = DIRECTION('',(5.275122655165E-17,0.227455280238,0.97378852709)); -#1403 = ORIENTED_EDGE('',*,*,#1404,.F.); -#1404 = EDGE_CURVE('',#1175,#1397,#1405,.T.); -#1405 = LINE('',#1406,#1407); -#1406 = CARTESIAN_POINT('',(5.649679875255,3.602918464526, - -13.21082950266)); -#1407 = VECTOR('',#1408,1.); -#1408 = DIRECTION('',(-0.349023821871,0.880598971639,-0.320511814002)); -#1409 = ORIENTED_EDGE('',*,*,#1174,.T.); -#1410 = ORIENTED_EDGE('',*,*,#1411,.T.); -#1411 = EDGE_CURVE('',#1177,#1395,#1412,.T.); -#1412 = LINE('',#1413,#1414); -#1413 = CARTESIAN_POINT('',(1.103762571829,7.940067898719, - -47.92064259636)); -#1414 = VECTOR('',#1415,1.); -#1415 = DIRECTION('',(-0.299648208284,0.896513522642,0.326304236859)); -#1416 = PLANE('',#1417); -#1417 = AXIS2_PLACEMENT_3D('',#1418,#1419,#1420); -#1418 = CARTESIAN_POINT('',(5.823691883056,3.068404028665, - -13.45978839622)); -#1419 = DIRECTION('',(0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1420 = DIRECTION('',(-0.340781908463,0.939692620786,2.907695487825E-02) - ); -#1421 = ADVANCED_FACE('',(#1422),#1432,.F.); -#1422 = FACE_BOUND('',#1423,.F.); -#1423 = EDGE_LOOP('',(#1424,#1425,#1431)); -#1424 = ORIENTED_EDGE('',*,*,#1404,.T.); -#1425 = ORIENTED_EDGE('',*,*,#1426,.T.); -#1426 = EDGE_CURVE('',#1397,#1185,#1427,.T.); -#1427 = LINE('',#1428,#1429); -#1428 = CARTESIAN_POINT('',(-5.275833888477,4.546144602338, - -13.55413574101)); -#1429 = VECTOR('',#1430,1.); -#1430 = DIRECTION('',(-0.349023821871,-0.880598971639,0.320511814002)); -#1431 = ORIENTED_EDGE('',*,*,#1184,.T.); -#1432 = PLANE('',#1433); -#1433 = AXIS2_PLACEMENT_3D('',#1434,#1435,#1436); -#1434 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -13.01628215822)); -#1435 = DIRECTION('',(2.88163763217E-16,0.342020143326,0.939692620786)); -#1436 = DIRECTION('',(-1.048830324052E-16,0.939692620786,-0.342020143326 - )); -#1437 = ADVANCED_FACE('',(#1438),#1449,.F.); -#1438 = FACE_BOUND('',#1439,.F.); -#1439 = EDGE_LOOP('',(#1440,#1441,#1442,#1443)); -#1440 = ORIENTED_EDGE('',*,*,#1192,.T.); -#1441 = ORIENTED_EDGE('',*,*,#1426,.F.); -#1442 = ORIENTED_EDGE('',*,*,#1394,.F.); -#1443 = ORIENTED_EDGE('',*,*,#1444,.F.); -#1444 = EDGE_CURVE('',#1193,#1395,#1445,.T.); -#1445 = LINE('',#1446,#1447); -#1446 = CARTESIAN_POINT('',(-0.871390517001,8.635298785064, - -47.66759924779)); -#1447 = VECTOR('',#1448,1.); -#1448 = DIRECTION('',(0.299648208284,0.896513522642,0.326304236859)); -#1449 = PLANE('',#1450); -#1450 = AXIS2_PLACEMENT_3D('',#1451,#1452,#1453); -#1451 = CARTESIAN_POINT('',(-5.782806207227,3.068404028665, - -13.93896851312)); -#1452 = DIRECTION('',(-0.93629059846,0.342020143326,-7.988827695448E-02) - ); -#1453 = DIRECTION('',(0.340781908463,0.939692620786,2.907695487825E-02) - ); -#1454 = ADVANCED_FACE('',(#1455),#1460,.F.); -#1455 = FACE_BOUND('',#1456,.F.); -#1456 = EDGE_LOOP('',(#1457,#1458,#1459)); -#1457 = ORIENTED_EDGE('',*,*,#1444,.T.); -#1458 = ORIENTED_EDGE('',*,*,#1411,.F.); -#1459 = ORIENTED_EDGE('',*,*,#1200,.T.); -#1460 = PLANE('',#1461); -#1461 = AXIS2_PLACEMENT_3D('',#1462,#1463,#1464); -#1462 = CARTESIAN_POINT('',(2.828438300639,3.068404028665, - -49.69378323641)); -#1463 = DIRECTION('',(0.,0.342020143326,-0.939692620786)); -#1464 = DIRECTION('',(0.,0.939692620786,0.342020143326)); -#1465 = ADVANCED_FACE('',(#1466),#1485,.T.); -#1466 = FACE_BOUND('',#1467,.T.); -#1467 = EDGE_LOOP('',(#1468,#1477,#1483,#1484)); -#1468 = ORIENTED_EDGE('',*,*,#1469,.T.); -#1469 = EDGE_CURVE('',#1470,#1470,#1472,.T.); -#1470 = VERTEX_POINT('',#1471); -#1471 = CARTESIAN_POINT('',(-11.6927539352,0.,-48.00951684793)); -#1472 = CIRCLE('',#1473,4.735522705283); -#1473 = AXIS2_PLACEMENT_3D('',#1474,#1475,#1476); -#1474 = CARTESIAN_POINT('',(-16.42827664048,0.,-48.00951684793)); -#1475 = DIRECTION('',(-0.,1.,0.)); -#1476 = DIRECTION('',(1.,0.,0.)); -#1477 = ORIENTED_EDGE('',*,*,#1478,.T.); -#1478 = EDGE_CURVE('',#1470,#1209,#1479,.T.); -#1479 = LINE('',#1480,#1481); -#1480 = CARTESIAN_POINT('',(-11.6927539352,-22.,-48.00951684793)); -#1481 = VECTOR('',#1482,1.); -#1482 = DIRECTION('',(0.,1.,0.)); -#1483 = ORIENTED_EDGE('',*,*,#1208,.F.); -#1484 = ORIENTED_EDGE('',*,*,#1478,.F.); -#1485 = CYLINDRICAL_SURFACE('',#1486,4.735522705283); -#1486 = AXIS2_PLACEMENT_3D('',#1487,#1488,#1489); -#1487 = CARTESIAN_POINT('',(-16.42827664048,-22.,-48.00951684793)); -#1488 = DIRECTION('',(0.,1.,0.)); -#1489 = DIRECTION('',(1.,0.,0.)); -#1490 = ADVANCED_FACE('',(#1491),#1499,.F.); -#1491 = FACE_BOUND('',#1492,.F.); -#1492 = EDGE_LOOP('',(#1493,#1494,#1495,#1496,#1497,#1498)); -#1493 = ORIENTED_EDGE('',*,*,#1264,.T.); -#1494 = ORIENTED_EDGE('',*,*,#1233,.T.); -#1495 = ORIENTED_EDGE('',*,*,#1352,.T.); -#1496 = ORIENTED_EDGE('',*,*,#1328,.T.); -#1497 = ORIENTED_EDGE('',*,*,#1304,.T.); -#1498 = ORIENTED_EDGE('',*,*,#1280,.T.); -#1499 = PLANE('',#1500); -#1500 = AXIS2_PLACEMENT_3D('',#1501,#1502,#1503); -#1501 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1502 = DIRECTION('',(0.,1.,0.)); -#1503 = DIRECTION('',(0.,0.,1.)); -#1504 = ADVANCED_FACE('',(#1505),#1508,.F.); -#1505 = FACE_BOUND('',#1506,.F.); -#1506 = EDGE_LOOP('',(#1507)); -#1507 = ORIENTED_EDGE('',*,*,#1369,.T.); -#1508 = PLANE('',#1509); -#1509 = AXIS2_PLACEMENT_3D('',#1510,#1511,#1512); -#1510 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1511 = DIRECTION('',(0.,1.,0.)); -#1512 = DIRECTION('',(0.,0.,1.)); -#1513 = ADVANCED_FACE('',(#1514),#1517,.F.); -#1514 = FACE_BOUND('',#1515,.F.); -#1515 = EDGE_LOOP('',(#1516)); -#1516 = ORIENTED_EDGE('',*,*,#1469,.T.); -#1517 = PLANE('',#1518); -#1518 = AXIS2_PLACEMENT_3D('',#1519,#1520,#1521); -#1519 = CARTESIAN_POINT('',(-45.46495478095,0.,-70.97315781796)); -#1520 = DIRECTION('',(0.,1.,0.)); -#1521 = DIRECTION('',(0.,0.,1.)); -#1522 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3) -GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1526)) -GLOBAL_UNIT_ASSIGNED_CONTEXT((#1523,#1524,#1525)) REPRESENTATION_CONTEXT -('Context #1','3D Context with UNIT and UNCERTAINTY') ); -#1523 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) ); -#1524 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) ); -#1525 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() ); -#1526 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(2.E-06),#1523, - 'distance_accuracy_value','confusion accuracy'); -#1527 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7)); -ENDSEC; -END-ISO-10303-21; diff --git a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl b/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl deleted file mode 100644 index 5c1f741349..0000000000 Binary files a/docs/CAD/design/mate-connectors/BearConnector_Female_Trimmed_wall.stl and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md b/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md deleted file mode 100644 index fe1a7a5fee..0000000000 --- a/docs/CAD/design/mate-connectors/DESIGN_MATE_CONNECTORS.md +++ /dev/null @@ -1,922 +0,0 @@ -# Mate connectors: aligning with the mainstream CAD systems - -Research date: 2026-08-05. Written against `orca_cad` / `Snapmaker` at the M8 state -(`CadDocument.{hpp,cpp}`, `apply_mate`, `datum_frame`, the `Mate` card in `DesignPanel.cpp`). - -**Brief:** align with the mate-connector concept as the main CAD programs actually implement it, -and be simple, unequivocal, unconfusing. Alignment is the organising principle of this document: -every recommendation is labelled either **[INDUSTRY]** — do what they all do — or **[DEVIATION]** — -we would be departing, here is why and what it costs. - ---- - -## 0. The answer in ten lines - -1. Seven systems surveyed. **Five of the seven use the same model**; two are the old world. -2. The model: a joint is defined between **two local coordinate frames**, one rigidly attached to - each part, plus **one type** naming which DOF stay free. -3. The frame is called a mate connector (Onshape), a **joint origin** (Fusion, Inventor), a joint - connector (FreeCAD 1.0). Same object, three names. -4. **Every one of them expresses every DOF about the frame's Z axis.** One axis, one convention. -5. **Five types appear in every frame-based system with identical names and identical DOF**: - Fastened/Rigid, Revolute, Slider, Cylindrical, Planar. Ball is in four of five. -6. That is not fashion — those are the classical **lower kinematic pairs**. The vocabulary converged - because the mechanics converged. -7. Our kernel is already on the right side of the line: frame-based, five types, Z-relative, - superimpose-then-relax. **The architecture needs no revisiting.** -8. Where we are out of step: connectors that are not attached to a body; an origin that can only be - a face centroid; no live preview of the two Z arrows; a mate card of abstract dropdowns. -9. Where we would knowingly deviate: refusing a second mate per body (no vendor does this — it is - forced on us by having no solver) and possibly inverting the default mate direction. -10. Biggest single win for the stated goal, and it costs no kernel work: **draw both frames and - ghost the result before Confirm.** The convention stops needing to be remembered. - ---- - -## 1. The two families - -**Constraint-based ("old CAD").** The user states pairwise *geometric relations* between raw -topology — this face coincident with that face, this axis concentric with that axis, this plane -parallel at 12 mm. Each relation removes some DOF; a numerical solver satisfies all of them at once. -Fully positioning one part typically takes **three or more mates**, and the set can be -over-constrained, under-constrained, or satisfiable in several configurations. - -**Frame-based ("mate connectors").** The user places a *local coordinate system* on each part and -states **one** relation between the two frames. The relation is not "these surfaces touch" but -"these frames coincide, except for the following DOF, which stay free." - -Onshape's help page opens by drawing exactly this line: - -> *"Mates in Onshape are different than mates in old CAD systems. Many assemblies require only one -> Onshape Mate between any two instances, as the movement (degrees of freedom) between those two -> instances is embedded in the Mate."* - -The frame-based model won for three reasons, all of which matter here: - -- **One mate per pair.** No mental arithmetic about which three constraints add up to a hinge. -- **The DOF are declared, not deduced.** A revolute mate *is* one rotation. You do not discover the - remaining freedom by dragging. -- **It needs no simultaneous solver for the common case.** Frame-to-frame alignment is a matrix - composition — precisely what `apply_mate` already does. - -> **Caveat — several vendors ship both, and "align with X" is therefore ambiguous.** **Inventor** -> kept its legacy constraints *and* added frame-based Joints in 2012; many Inventor users still build -> assemblies entirely with the old constraint stack. **Creo** has placement constraints *and* -> Mechanism connections. **FreeCAD** had constraint-based Assembly2/3 add-ons before the frame-based -> Assembly workbench shipped in 1.0. So copying "what Inventor does" means copying **one of two -> coexisting workflows**. **Onshape and Fusion 360 are the only pure frame-based examples**, and they -> are the ones to weight most heavily when the evidence conflicts. - ---- - -## 2. Field survey — seven systems - -| | Onshape | Fusion 360 | Inventor | FreeCAD 1.0 | Creo | Siemens NX | SOLIDWORKS | -|---|---|---|---|---|---|---|---| -| **Family** | Frame | Frame | Frame (+ legacy constraints) | Frame (+ legacy add-ons) | Both | Constraint | Constraint | -| **Frame object** | Mate connector | Joint origin | Joint origin | Joint connector (`Placement1/2`) | CSYS on `Weld`/`6DOF` | — | — (nearest: **mate reference**) | -| **Where it lives** | Part Studio **and** Assembly; in the feature list | Component, inside the joint | Component / inside the joint | Inside the Joint object | Part | — | Part (up to 3 named entities) | -| **Origin placement** | Inferred family on hover; `Shift` locks | Discrete **snap points**; `Ctrl` cycles | Snap points + explicit origins | Inferred, previewed on hover | Picked CSYS | Picked entities | Picked entities | -| **Orientation control** | Primary axis (Z) + secondary axis; flip + 90° reorient | Flip, angle, offsets | Flip, angle, offsets | `Placement1/2` + `Offset1/2` | CSYS + offset | — | — | -| **Type inference** | No — explicit | No — explicit | **Yes — "Automatic"** from picked geometry | No | No | No | Partial (mate reference type) | -| **Solver** | Yes, simultaneous — *"order won't affect a Mate"* | Yes | Yes | Yes (Ondsel) | Yes | Yes | Yes | -| **Reuse across instances** | **Yes** — a Part Studio connector exists on every instance | Weak | Partial | Per-joint | Interfaces | Product Interface | Mate references auto-mate on insert | - -Three observations that shape everything below. - -- **Every frame-based system reduced the type list by an order of magnitude** relative to SOLIDWORKS - (7–13 vs ~25) and lost nothing. That is not simplification-by-omission; it is what happens when the - DOF live in the mate instead of being assembled from constraints. -- **Every one of them defines its types relative to a single axis.** Slider translates along Z, - Revolute rotates about Z, Cylindrical does both, Planar translates in X/Y and rotates about Z. - One axis carries the whole vocabulary. -- **Onshape alone treats the connector as a first-class, reusable, named object** — and that is also - where its worst usability complaints come from (§4). - ---- - -## 3. The type vocabulary — cross-system table - -DOF = degrees of freedom left **free**, stated about/along the connector Z. - -| DOF | Onshape | Fusion 360 | Inventor | FreeCAD 1.0 | Creo | **Ours today** | -|---|---|---|---|---|---|---| -| 0 | Fastened | Rigid | Rigid | Fixed | Rigid / Weld | **Fastened** ✅ | -| 1 — rot Z | Revolute | Revolute | Rotational | Revolute | Pin | **Revolute** ✅ | -| 1 — trans Z | Slider | Slider | Slider | Slider | Slider | **Slider** ✅ | -| 2 — rot + trans Z | Cylindrical | Cylindrical | Cylindrical | Cylindrical | Cylinder | **Cylindrical** ✅ | -| 3 — trans XY + rot Z | Planar | Planar | Planar | *(Parallel+Distance)* | Planar | **Planar** ✅ | -| 3 — rot XYZ | Ball | Ball | Ball | Ball | Ball | — | -| 2 — different axes | Pin slot | Pin-Slot | — | — | Slot / Bearing | — | -| 1 — coupled | Screw | — | — | Screw | — | — | -| 4 | Parallel | — | — | Parallel | — | — | -| other | Tangent, Width, Group | As-built | Automatic | Perpendicular, Angle, Distance, Gears, Belt, RackPinion | General, 6DOF | — | - -**Five types appear in every frame-based system, with the same name and the same DOF.** Those five -are the industry's common denominator, and they are exactly `mate_kind` 0–4 as already implemented. -Ball is in four of five. Everything past that is a long tail no two vendors agree on. - -### Why the convergence is a fact, not a fashion - -A rigid-body placement is an element of SE(3). A mate leaves some set of relative motions free. For -the mate to behave the same throughout its range — for a hinge to be a hinge at every angle — that -free set must be **closed under composition**: two allowed motions must compose to an allowed motion. -A closed set of motions is a **subgroup** of SE(3). - -The subgroups corresponding to physical surface-on-surface contact are the classical **six lower -pairs** (Reuleaux): - -| Pair | Free motion relative to Z | DOF | -|---|---|---| -| Revolute (R) | rotation about Z | 1 | -| Prismatic / slider (P) | translation along Z | 1 | -| Helical / screw (H) | coupled rotation + translation | 1 | -| Cylindrical (C) | rotation about **and** translation along Z | 2 | -| Planar (E/G) | translation in X,Y + rotation about Z | 3 | -| Spherical / ball (S) | rotation about X, Y, Z | 3 | - -Plus the two trivial ends: identity (0 DOF — **fastened**) and all of SE(3) (6 DOF — floating, i.e. -no mate). Hervé's Lie-subgroup analysis of the displacement group is the standard reference for -treating these as the algebraic building blocks of mechanism synthesis. - -**Consequence.** Anything outside this table is either (a) a *composition* needing a solver, or -(b) not a joint at all but a *measurement*: - -- Onshape's **Parallel** (4 DOF), **Tangent**, **Width**, **Pin slot**, and FreeCAD's **Distance / - Angle / Perpendicular** are constraints, not pairs — their free set is not a subgroup, so they only - make sense alongside a simultaneous solver. -- **Gear, Belt, Rack-and-pinion** are *relations between two mates*, a different object entirely. -- **Screw (H)** is a legitimate lower pair but needs a pitch parameter and is rare in printed parts. - -So the vendors' shared five, the lower pairs, and our `mate_kind` 0–4 are the same list arrived at -three ways. **[INDUSTRY] Stop looking for missing types and spend the budget on the connector.** - ---- - -## 4. What they all agree on — adopt verbatim - -Deviating from any of these makes an experienced user's intuition *wrong*, which is the operational -definition of "confusing". - -**A1 [INDUSTRY] — The connector is a full right-handed frame.** -Origin + Z (primary) + X (secondary). Onshape and Fusion expose exactly these two axis controls and -nothing else. A point cannot express spin; an axis cannot express clocking. -*Status: we comply* — `DatumCoordSys` carries origin/x/y and derives Z. - -**A2 [INDUSTRY] — Z is the joint axis; every DOF is about or along Z.** -Revolute rotates about Z. Slider translates along Z. Planar's free plane is normal to Z. Offsets run -along Z. This single rule is what makes the system learnable: **one axis to look at, and its meaning -never changes.** -*Status: we comply* — `mate_offset` along A's z, `mate_angle` about A's z. - -**A3 [INDUSTRY] — Mating superimposes the two frames; the type then relaxes specific DOF.** -FreeCAD states it most plainly: *"the second connector is superimposed on the first connector by -default and may change its position according to the joint type."* Fastened is not a special case — -it is the base case with nothing relaxed. -*Status: we comply* — `T = M_A · Rz · Tz · F · M_B⁻¹`, looser kinds relaxing from there. - -**A4 [INDUSTRY] — The connector belongs to a part and moves with it.** -Onshape: a connector defined in a Part Studio *"is available for reuse on every instance of that part -in every assembly in which it is instanced."* It is part geometry, not assembly geometry. -*Status: **violated**.* `CoordSysType::PointWorld` is a bare world XYZ with `X = world X` and no -`coordsys_body`. Such a connector does not follow its part. See §6 G1. - -**A5 [INDUSTRY] — Selection order is meaningful and must be visible.** -One connector is the reference; the other is driven onto it. Onshape spells out that offsets are -measured *"from the second Mate connector selected to the first"*, and that reversing the order -flips the sign. -*Status: complied with in the data model* (`mate_cs_a` fixed, `mate_cs_b` moves) *but not in the UI* — -two dropdowns labelled A and B do not tell the user which part is about to jump. - -**A6 [INDUSTRY] — Flip and re-clock live in the mate dialog, always.** -Onshape: *"Click the arrow icon to flip the direction of the primary axis. Click the Reorient -secondary axis icon to rotate the secondary axis in 90-degree increments."* -*Status: partial.* We have `mate_flip` (Z reversal). We have `mate_angle` as a free number — strictly -more powerful than 90° steps, and much worse to *use*: the common case is "it came in a quarter turn -out", and typing 90 is a worse gesture than pressing a button. - -**A7 [INDUSTRY] — DOF are shown, not inferred by the user.** -Onshape animates each mate's remaining DOF on demand; Fusion and Inventor name the DOF in the type -list. Our dropdown text already does this in words ("free spin + axial slide"). Keep it. - -**A8 [INDUSTRY] — Free DOF are preserved from the current placement, not zeroed.** -Onshape: a Planar mate aligns the frames *"but they are not restricted to this location with respect -to their degrees of freedom."* -*Status: we comply* — and it must be *said*, because a Planar mate that leaves the part where it was -looks like a mate that did nothing. - ---- - -## 5. Where they diverge — who to copy, and why - -### D1 — Where the connector's origin comes from - -| | Behaviour | -|---|---| -| **Fusion 360** | Discrete **snap points** only: vertex, edge midpoint, face centre, arc centre. `Ctrl` cycles the candidates under the cursor. A circle icon denotes a vertex, a triangle a midpoint. "Between two faces" is a separate explicit option. | -| **Onshape** | Infers a *family* on hover — centroid, every vertex, every edge midpoint, every arc centre, the centroids of interior regions (holes, slots), and the virtual sharps of conical faces. `Shift` locks the current candidate. | -| **Inventor** | Snap points, plus explicit joint origins for awkward cases. | -| **FreeCAD 1.0** | Hovering previews where the connector will land before you commit. | -| **Ours** | Always the **face centroid**. No alternative exists. | - -Onshape's richness has a cost its own documentation admits: *"The suggested locations are based on -the underlying geometry of the part and changing the geometry will change the location of the Mate. -This can be undesirable in certain situations."* On the forum this shows up as connectors that move -or break on edit — the classic topological-naming failure. Fusion's discrete set is poorer and far -more predictable. - -> **[INDUSTRY] Copy Fusion's candidate *set*.** A small, closed, enumerable set — **face centroid, -> vertex, edge midpoint, arc/circle centre** — each drawn before commit, with the card naming which is -> in use ("Origin: edge midpoint"). This is our largest expressiveness gap: a face centroid alone -> cannot place a hinge pin on a corner boss. It is also the one place where copying the *simpler* -> vendor is clearly right. -> -> **Open sub-choice — how the candidate is chosen.** Three options, in increasing order of magic: -> (1) **explicit dropdown** in the card after picking the face — no hover behaviour at all; -> (2) **Fusion's `Ctrl` cycling** through candidates under the cursor; (3) **Onshape's hover -> inference**. Kimi's independent review argued for (1) on the grounds that hover is exactly where -> both vendors' instability complaints originate, and that a dropdown gets ~90% of the expressiveness -> with none of the hover-guess debugging. That is a fair reading and (1) is the cheapest to build and -> the easiest to make unequivocal. **Recommendation: build (1) first; if hover is added later, let it -> *pre-fill the dropdown* rather than silently create an implicit connector** — which also keeps R2 -> (one kind of connector) intact. - -### D2 — Explicit type, or inferred from the geometry? - -Inventor is the only surveyed system that infers: *"Rotational is selected if the two selected -origins are circular. Cylindrical if the two selected origins are points on a cylinder. Ball if -points on a sphere. Rigid for all other origin selections."* Onshape and Fusion require an explicit -choice. - -> **[INDUSTRY, Inventor] Do both, in Inventor's order.** Infer a *default* type from what was picked, -> then show it in an editable control. Inference is what makes the tool feel like it understands the -> geometry; the visible, editable result is what keeps it unequivocal. Pure inference with no visible -> type is the confusing option; a pure dropdown with no default is the tedious one. This also fits -> the Design tab's geometry-first charter exactly: point at a bore, get Revolute offered. - -### D3 — How the Z-direction ambiguity is resolved - -This is the specific failure the brief is aimed at. A former IT trainer stated it precisely on the -Onshape forum: - -> *"There is always the risk that users will build their own conceptual models of how software works -> which may not match the designer's concept. The result is usually a poor user experience and many -> mistakes… for a good (say) Fixed mate to occur do the Z axes of the two mates have to be pointing -> in the same direction… Alternatively, should they be facing each other?"* - -He is asking the right question and **no vendor's documentation answers it.** Onshape's own advice — -*"if the behavior is not what you expected, try flipping the primary and/or secondary axis"* — is -trial and error. This is a gap in the industry, not a convention to copy. - -> **[INDUSTRY, method] Resolve it with live preview, not documentation.** FreeCAD previews the -> connector on hover; Onshape and Fusion both draw the frames. Draw **both** Z arrows the moment the -> second connector is picked, and ghost the resulting placement *before* Confirm. The convention then -> never has to be remembered because it is on screen. -> -> **[DEVIATION, optional] Name the two cases in the user's words** rather than in axis-speak: -> "the two faces come together" vs "the axes run the same way". No surveyed vendor does this — they -> all ship a flip arrow. It is a small, low-risk improvement on the state of the art, and it is -> separable from the default-direction question in §8 D1. - -### D4 — Named, reusable connectors on the part - -Onshape: connectors created in the Part Studio are reused on every instance in every assembly. -SOLIDWORKS' **mate reference** reaches the same end by another route: up to three named entities -(primary/secondary/tertiary) baked into the part so it auto-mates on drag-and-drop — and a *named* -mate reference seeks out a matching name on insertion. That naming trick is how a library of -fasteners assembles itself. - -> **[INDUSTRY] Out of scope now, but do not preclude it.** Give connectors a stable, user-visible -> name at creation. One string today; expensive to add once documents exist in the wild. - ---- - -## 6. Confusion catalogue - -Documented ways real implementations confuse people. Each is a requirement in disguise. - -**C1 — Which way does Z point?** See D3. If a user has to ask once, they will mis-predict a hundred -times. - -**C2 — The roll is unspecified.** Aligning Z leaves one rotation about Z undetermined. Something must -pin it, and if that something is world-derived, the frame does not rotate with its part. **This -codebase shipped exactly this bug** (`en4`): a face-only connector took Z from the face -normal but X from `coordsys_x_hint`, a world constant, so Fastened and Slider claimed to lock an -orientation the frame could not see. Fixed 2026-07-26 by deriving X from the face's own first usable -edge — but note the fix's own caveat: *"replaying an older document whose face-only connector fed a -mate can now place that body differently."* Roll conventions are load-bearing, and changing one is a -document-format change. - -**C3 — The origin drifts.** See D1. - -**C4 — Implicit and explicit connectors are not the same thing.** On the Onshape forum, implicit -connectors are reported to change their query structure when a feature is edited and re-accepted, and -are unusable in places explicit ones work. Two things called by one name that behave differently is a -permanent tax. - -**C5 — Which part moves?** A frame alignment is asymmetric. If the UI does not say which frame is -driven, the user finds out by watching the wrong part jump. - -**C6 — Which direction is a positive offset?** Onshape measures *"from the second Mate connector -selected to the first"* — the sign depends on pick order, and swapping the picks flips it. Documented -behaviour, documented surprise. - -**C7 — One intent, several mates.** The SOLIDWORKS failure: expressing "this shaft is in this hole, -resting on this shoulder" as three constraints, then discovering the solver picked the mirror -configuration. Frame-based systems fix this by construction; the requirement is not to reintroduce it. - -**C8 — Degenerate frames.** A circular face has no usable in-plane edge direction; a cylinder seam -projects to nothing; a picked edge parallel to Z gives a zero cross product. `datum_frame` handles all -three with fallbacks — the requirement is that a fallback be *visible*, because a silent fallback is -C2 wearing a different hat. - -**C9 — Order dependence without a solver.** Onshape can say *"Onshape solves Mates simultaneously so -order won't affect a Mate."* A system that composes transforms in tree order cannot say that. Two -mates driving one body means the second wins and the first is a lie on screen. - -**C10 — Mirrors and patterns.** A mirrored instance has a left-handed frame. Blindly mirroring a -connector gives a frame whose Z still points "out" but whose handedness flipped, so every rotation -runs backwards. Cheap to handle now, miserable to retrofit. - ---- - -## 7. Requirements - -Labelled **[INDUSTRY]** (what the frame-based systems do) or **[DEVIATION]** (we would depart). - -### Definition - -**R1 [INDUSTRY] — A mate connector is a frame attached to exactly one body.** No body, no connector. -*Test:* creating a connector without a body is rejected at creation, not at mate time. -→ **`CoordSysType::PointWorld` violates this.** It is a datum wearing a connector's name. - -**R2 [INDUSTRY] — One kind of connector, not two.** No "implicit" connector that behaves differently -from an explicit one. If hover inference is offered, hovering *creates* an ordinary connector. -*Why:* C4. *Test:* everything that accepts a connector accepts any connector. - -**R3 [INDUSTRY] — A mate names exactly one subgroup of free motion.** Fastened (0), Revolute (1), -Slider (1), Cylindrical (2), Planar (3), optionally Ball (3). *Why:* §3. *Test:* every type's free -set is closed; no type is "A and also B". - -### Orientation - -**R4 [INDUSTRY] — Everything is about Z. Say so once, in the UI.** *Test:* no mate parameter refers -to any other axis. - -**R5 [DEVIATION] — Z is the outward material direction, and mates default to FACING.** -A mate would drive B's Z onto **−A's Z** by default, so picking two faces that should touch makes -them touch with no options changed. *Why:* it is the whole of C1. -**Cost and caveat:** this inverts today's default (`mate_flip=false` currently *aligns*), and I could -not establish from any vendor's documentation what their default actually is — the forum question in -D3 went unanswered precisely because it is undocumented. So this is marked a deviation on the honest -grounds that **I cannot prove the industry agrees with it.** If D3's live preview lands first, the -default matters much less, because the user sees the outcome before committing. See §9 D1. - -**R6 [DEVIATION] — Name the two directions; do not ship a boolean called "flip".** -`Direction: Facing | Aligned`. Every surveyed vendor ships a flip arrow instead. A boolean requires -remembering what unticked means; two named values do not. Low risk, small improvement on the state of -the art. - -**R7 [INDUSTRY] — Roll is picked, or a stored quarter turn. Never world-derived.** -X from a referenced edge or in-plane direction; failing that, a deterministic body-attached seed, with -**Rotate 90°** offered as a stored integer 0–3 on top (this is Onshape's "reorient secondary axis", -A6). *Why:* C2 and the world-constant bug this project already shipped. *Test:* rotate the parent -body by any angle; the connector's X rotates with it — *this test already exists* ("a face-only frame -rotates with its body"). - -**R8 [INDUSTRY] — A degenerate roll is reported, not absorbed.** *Test:* a connector on a full -cylindrical face reports "roll undefined — pick a direction" rather than silently taking a fallback. - -### Placement - -**R9 [INDUSTRY, Fusion] — Origin comes from a small closed set of named candidates.** -**Face centroid, arc/circle centre, edge midpoint, vertex.** Four. Each stored as -`(kind, topological reference)` and resolved at rebuild. *Why:* D1. *Test:* the stored kind is visible -in the card; a rebuild either resolves it or raises an error. - -**R10 [INDUSTRY] — An unresolvable reference is an error, never a silent relocation.** -*Test:* delete the referenced face; the mate reports "connector A: face not found" and the body stays -where it was. - -### Semantics without a solver - -**R11 [DEVIATION] — A body is driven by at most one mate. The second is refused.** -**No surveyed system does this** — they all have solvers and all accept many mates per body. It is -forced on us by tree-order composition: a second mate on the same body silently overrides the first -and the screen shows a configuration satisfying only one stated intent (C9). *Test:* creating a -second mate whose moving body already has one is rejected, naming the existing mate. -This is the single largest departure in this document. See §9 D4. - -> **A tempting misreading, checked and rejected.** It is easy to find the claim that Onshape mandates -> *"exactly one Mate between any two instances"*, which would make R11 an industry agreement rather -> than a deviation. **The Onshape page does not say that.** It says *"**Many assemblies require only** -> one Onshape Mate between any two instances"* and then lists, as an explicit remedy, *"**Use more -> than one Mate if necessary.**"* One mate per pair is Onshape's *typical case*, not its rule. R11 -> remains a deviation and must be justified on our own architecture, not on theirs. - -**R11a [DEVIATION] — The refusal list.** With no solver, these are unsupportable and must be refused -rather than half-done: a second mate on an already-driven body; cycles (A→B, B→A); closed loops -(A→B, A→C, B→C); relations *between* mates (gear, belt, rack-and-pinion, screw coupling); **joint -limits**, which nothing can enforce without a solver; and **dragging a body to exercise a free DOF**, -which requires keeping the body on the allowed manifold. Motion analysis and animation follow from the -same lack. *Requirement:* none of these may appear in the UI as something that half-works. - -**R12 [DEVIATION] — The mate graph is an acyclic forest rooted at fixed bodies.** A body reached by -no mate is fixed; cycles are refused. Same root cause as R11. *Test:* A→B, B→A rejected at creation. - -**R13 [INDUSTRY] — Free DOF are preserved from the current placement, and the user is told.** -Behaviour already matches Onshape (A8); the telling does not. *Test:* the card for any type with -DOF > 0 says which motions remain and that dragging exercises them. - -**R14 [INDUSTRY] — State what mirroring does to a connector.** -*Checked in the code:* `datum_frame` ends with a Gram-Schmidt forcing a right-handed frame -(`ds.x = Y.cross(Z)`), so a connector resolved on a mirrored body comes out **right-handed, not -mirror-imaged**. Z follows the mirrored face's outward normal, X follows a mirrored edge, handedness -is re-imposed. Defensible — a mate on the mirrored part still turns the way its type says — but it -means a mirrored sub-assembly is *not* the mirror image of the original in its rotation sense. -*Requirement:* document it and pin it with a test. *Why:* C10. - -### Feedback — the part that actually removes confusion - -**R15 [INDUSTRY] — Before Confirm, the card answers four questions in words.** Which body moves; -which way Z points on each connector; how many DOF remain; what the offset is measured from. - -**R16 [INDUSTRY] — Draw both frames live, with Z distinguishable, and ghost the result.** -Two triads with Z rendered differently from X/Y (length, arrowhead, colour). *Why:* D3 — the fastest -way to make a convention unequivocal is to show it. *Test:* both Z directions are readable in a -screenshot. - -**R17 [INDUSTRY] — Show the DOF budget per body.** "Body 2: 1 of 6 DOF free (rotation about Z)." -The most educational readout in any assembly system, and free to compute here — the type *is* the DOF -count. *Test:* the number changes when the type changes. - -**R18 [DEVIATION] — Refuse loudly and name the alternative.** Where something is out of scope (a -second mate, a tangency, a gear ratio), say what is unsupported and what to do instead. Vendors do not -need this because their solvers accept the input. *Test:* no refusal message ends without a suggested -next action. - ---- - -## 8. Minimal specification, and gap analysis - -### The connector - -``` -MateConnector - body int required, ≥ 0 (R1) - origin_kind enum FaceCentroid | ArcCentre | EdgeMidpoint | Vertex (R9) - origin_ref topo ref face / edge / vertex index on that body - z_source implied by origin_kind: face normal, arc axis, edge tangent - roll_ref topo ref optional in-plane edge; else deterministic seed (R7) - roll_quarters int 0..3 stored quarter turns on top of the seed (R7, A6) - flip_z bool reverse Z at the connector - name string stable, user-visible (D4) -``` - -`flip_z` is a property of the **connector**, chosen once when it is made — not a per-mate -afterthought. Keeping connector-flip and mate-direction separate is what stops the "which flip do I -tick?" question. - -### The mate - -``` -Mate - kind enum Fastened | Revolute | Slider | Cylindrical | Planar [| Ball] (R3) - fixed connector A — its body does not move - moving connector B — its body is driven (A5, C5) - direction enum Facing | Aligned (R5, R6) - offset mm along A's Z, measured A → B — state this in the label (C6) - angle deg about A's Z (R4) -``` - -Within one field of what exists. - -### Gaps against today - -Source of record: `CadDocument.hpp:26,247-252,298-310`; `CadDocument.cpp:1669` (`datum_frame`), -`:2961` (`apply_mate`), `:1302` (`add_mate`); `DesignPanel.cpp:2671-2709` (the Mate card). - -| # | Gap | Severity | Ref | -|---|---|---|---| -| G1 | `PointWorld` connectors are not attached to a body and their X is a world constant | **High — data model** | A4/R1 | -| G2 | Origin is always the face centroid; no vertex / edge-midpoint / arc-centre snap | **High — expressiveness** | D1/R9 | -| G3 | No live preview of the two Z arrows or of the resulting placement | **High — this is the brief** | D3/R16 | -| G4 | Mate card is two abstract dropdowns; nothing says which body moves | High — charter + A5 | R15 | -| G5 | No joint-type inference from the picked geometry | Medium — feel | D2 | -| G6 | `add_mate` validates nothing — no one-mate-per-body, no cycle check | Medium | R11/R12 | -| G7 | No `Ball` type | Low | §3 | -| G8 | Re-clocking needs a typed angle; no 90° step control | Low, cheap | A6/R7 | -| G9 | Degenerate roll falls back silently | Low | C8/R8 | -| G10 | Connectors have no stable user-facing name | Low now, expensive later | D4 | - -**Already aligned — do not "fix" these:** the five types and their DOF; the frame definition (A1); -Z as the joint axis (A2); superimpose-then-relax (A3); the fixed/moving asymmetry in the data model -(A5); DOF wording in the type list (A7); free-DOF preservation (A8); right-handed frames under mirror -(R14); and `en4`'s fix, which put roll derivation on the body where it belongs (C2). - -**The pattern worth naming: the kernel is in good shape and the concept is under-explained.** Half the -requirements here are wording and drawing, not geometry. The two real engineering items are R9 (origin -candidates) and R11/R12 (the mate-graph rules). - -### Expensive-to-retrofit decisions — get these right in the data model now - -Changing any of these after documents exist in the wild costs a migration, not an edit. - -1. **Topological reference stability.** Storing raw face/edge indices is brittle — editing a body - renumbers faces. Either persistent topology IDs, or store the named origin *kind* plus a - deterministic search that re-finds the same geometric intent on rebuild. The latter is cheaper and - probably sufficient here; it is also what makes R10's "error, never silent relocation" enforceable. -2. **Connector ownership** (R1). Remove `PointWorld` or bind it to a body. Do this first. -3. **Mate direction semantics** (R5/D1). Inverting the default rewrites the meaning of every saved - mate. -4. **Roll representation** (R7). "First usable edge" is better than world-X but still fragile. Store - an explicit roll reference plus quarter turns. -5. **Coordinate convention** — Z = joint axis, X = roll reference. Changing this after release - invalidates every mate. -6. **Units** — offset in mm, angle in degrees. Never change. -7. **Mirror handedness** (R14) — document the decision, do not let it stay an accident. -8. **Flat body index vs. a component tree.** Mates currently reference bodies in a flat vector. If - **sub-assemblies** are ever in scope, mates must reference nodes in a tree instead. Retrofitting - this is painful and it is the one item on this list not already implied elsewhere in the document — - **decide now whether nested assemblies are in scope.** -9. **Serialization field semantics.** Adding fields is easy; redefining `mate_flip` or - `coordsys_x_hint` is not. -10. **The one-mate-per-body rule** (R11). Enforce at creation. Relaxing it later by adding a solver is - straightforward; allowing many mates now and discovering later that they silently conflict is not. - ---- - -## 8b. The visual shape of the connector — polarity and verse - -Researched separately (2026-08-05) by downloading and **looking at** the vendors' own figures, not -by reading their prose. Files kept alongside this document in `doc/design/mate-connectors/`. - -### What the systems actually draw - -**Onshape** — verified from `planarfacemateconnectors.png`, `cylindricalmateconnectors.png`, -`linearedgemateconnectors.png`, `mateconnector-planarpoints.png`, `matepointiconLG.png`: - -> **A small circle with one quadrant filled, plus three short coloured axis arms (X red, Y green, -> Z blue).** - -Three parts, each doing one job: - -| Element | What it says | -|---|---| -| The **circle** | "I am a frame, and this is my XY plane." | -| The **filled quadrant** | **The roll.** The shaded sector is the +X/+Y quadrant. | -| The **coloured arms** | The three axis directions, Z distinguished by colour. | - -The quadrant is the cleverest part of the whole design and it is easy to miss. The figure -`matepointreorientsecondaryaxis.png` shows three connectors side by side with the quadrant in three -different rotations — **it is the live readout of "reorient secondary axis in 90° increments" (A6).** -One glyph element makes the otherwise-invisible clocking visible, and makes the 90° button's effect -legible before you commit. The toolbar icon `matepointiconLG.png` is that same circle-with-a-quadrant, -so the symbol is consistent from toolbar to viewport. - -Candidate snap points, before you choose one, are drawn as **plain small white dots** on the model -(clear in `mateconnector-planarpoints.png`: dots at every corner and edge midpoint). Candidate and -committed are deliberately different weights — dots propose, the circle-and-triad commits. - -**FreeCAD 1.0** — verbatim from the wiki: *"Connectors are local coordinate systems and are marked by -a symbol with three axes (X, Y, Z) and a circle representing the XY-plane."* Same core as Onshape — -circle plus triad — **without** the quadrant. - -**Fusion 360** — the joint origin glyph, plus a documented icon language for *candidates*: *"A circle -denotes a vertex, and a triangle denotes a midpoint."* Shape encodes what kind of point it is. - -**Convergent core:** *circle for the XY plane + coloured triad*. Onshape alone adds the roll quadrant. - -### What none of them draw — and it is exactly what was asked for - -**Nothing in any vendor's glyph says which connector is the reference and which one is about to -move.** Both ends of a mate are drawn identically. That is confusion C5 ("which part moves?") left -unsolved in the visual language, and it is why the honest recommendation earlier was a live ghost — -the ghost compensates for a glyph that does not carry the information. - -So the two things asked for split cleanly, and only one of them is solved upstream: - -- **Verse** (*verso* — which way it points): **solved**. Z has a colour and a direction. -- **Polarity** (which end receives, which end inserts; who is anchored, who travels): **unsolved - everywhere.** This is open ground, and getting it right is a genuine improvement rather than a - deviation to justify. - -### Our starting point - -**We draw nothing.** `resolve_datum_coordsys()` (`CadDocument.cpp:1749`) has exactly one consumer in -the entire tree — `McpControl.cpp:1310`, the agent socket. A mate connector is today visible only to -a program. The glyph is unbuilt, so there is no migration cost to designing it properly now. - -### Proposed glyph: the magnet - -Adopt Onshape's proven core, then add the missing polarity with a metaphor that carries its own -instructions. - -``` - ▲ solid cone on +Z ONLY ← verse - | - ────●──── ← the disc = XY plane, ● = exact origin - ▨ quadrant filled ← roll / clocking, steps 90° -``` - -**Rule 1 — verse: draw +Z and never −Z.** A single stem with a cone head, on the positive side only. -No stem below the disc. A double-headed axis is the one thing that guarantees the question gets asked; -an arrow that exists on one side only cannot be misread. Length is asymmetric on purpose. - -**Rule 2 — roll: keep Onshape's quadrant.** Filled sector = the +X/+Y quadrant. It rotates in 90° -steps with the reorient control (A6/R7). This is aligned *and* it is the only in-glyph answer to -"where is X?", which matters because Fastened and Slider lock the clocking. - -**Rule 3 — polarity: solid cone travels, open collar receives.** -- The **driven** connector (B, on the body that will move) draws a **solid filled cone** — the plug. -- The **fixed** connector (A) draws an **open ring / hollow cone outline** — the socket. - -Same silhouette, so they read as a matched pair; opposite fill, so which one is about to jump is -answerable at a glance and without a legend. Plug-into-socket is the one mechanical metaphor every -user of this tool already has in their hands. - -**Rule 4 — the pair reads as a magnet.** Draw a dashed line joining the two origins the moment both -are picked. Two poles, one field line. And because a magnet's north seeks a south, **"facing" becomes -the self-evident default** — which quietly settles open decision D1 (§9) on visual grounds rather than -on a convention nobody can look up. If the glyph looks like a magnet, nobody has to be told that two -faces which touch have opposed normals. - -**Rule 5 — three states, three weights.** - -| State | Drawing | -|---|---| -| **Candidate** (hover) | small dot only — Onshape's white dots; shape may encode kind, Fusion-style | -| **Picked** | full glyph: disc + quadrant + cone | -| **Degenerate roll** (C8/R8) | the quadrant is drawn **hollow/hatched** — "roll undefined, pick a direction" | - -That last row is worth the trouble: it turns R8 from a message nobody reads into a mark you cannot -miss, and it costs one branch in the renderer. - -**Rule 6 — do not reuse the existing triad.** The bed-centre world triad -(`DesignCanvas.cpp:65`, `set_axes_at_bed_center`) and the move gizmo are already three-coloured arrows. -The connector must not be a fourth set of RGB arrows or the viewport becomes unreadable. The disc and -the quadrant are what distinguish it; keep the arms short, and consider drawing only Z on the -committed glyph, with X/Y implied by the quadrant. - -### Built and judged in the viewport, not in a mock - -The browser mock that first accompanied this section was the wrong instrument and its proportions -were meaningless: **every gizmo in this codebase is sized in SCREEN PIXELS** via `upp = 1/zoom` -(`render_shell_gizmo` uses `15.0 * upp`, `render_hole_gizmo` `9.0 * upp` for its cube). A connector -is a symbol, not a part — it must not shrink with the model. Nothing about that is visible in SVG. - -The glyph was therefore implemented and driven on the rig. Screenshots: `g-0*.png`, left in the workspace `artifacts/shots/` and not moved into the repo. -Five findings, none of which a mock could have produced: - -**F1 — Three axis arms lose to one.** Rendered side by side (`ORCA_CAD_GLYPH=A` vs default), the -Onshape-style RGB trio crowds a 22 px disc: the arrowheads are as large as the disc, they bury the -gold quadrant, and at an oblique angle the three heads pile into a coloured smudge. Worse, **it is -indistinguishable from the move gizmo and the bed triad**, which are already RGB arrow trios in this -viewport. One-sided Z wins on evidence, not taste. (`g-01-zoom.png` vs `g-02-zoom.png`.) - -**F2 — Polarity works, and colour does more of the work than fill.** A filled blue head against an -open grey outline head is readable instantly at 22 px (`g-03-zoom.png`). But the fill difference is -the *second* cue; the colour split carries it. Keep both — fill survives greyscale and colour-blind -palettes, colour survives small size. - -**F3 — Depth off floats, depth on tears.** With `GL_DEPTH_TEST` off, connectors on faces pointing -*away* from the camera still drew their discs over the solid, so the part looked covered in frames -that were really on its back. Turning depth on fixed that and immediately caused **z-fighting**: the -disc is exactly coplanar with its face, and came out as a broken dotted arc. The fix is depth **on** -plus a sub-pixel lift along Z (`0.7 * upp`), scaled by `upp` so it never becomes a visible gap on -zoom-in. Both failure modes are in the images (`g-03` torn, `g-04` clean). - -**F4 — The quadrant is the first thing to die at a grazing angle.** On a face seen nearly edge-on the -disc foreshortens to a sliver and the fan collapses into a blob (`g-01-zoom.png`, lower-right glyph). -The roll is exactly the information that is hardest to read when you most need it. Not yet solved — -see the open item below. - -**F5 — Roll-undefined in red is too loud.** It works, but it makes the *least* important connector -the most eye-catching thing on screen. Amber, or the same grey with a hatched quadrant, is enough. - -Also surfaced while testing, and unrelated to the glyph: `add_mate` accepted a mate between two -connectors **on the same body**, which is meaningless, and duly transformed the body relative to -itself. Concrete instance of gap G6. - -**Still untested:** a true grazing view (the view-cube click missed), a connector on a curved face, -and behaviour when a connector overlaps the move gizmo. F4 is the open design question — the disc may -need to billboard its *quadrant* while keeping the disc in-plane, which is a compromise no surveyed -vendor makes and which should be tried before being adopted. - -### What this costs - -A renderer for `resolve_datum_coordsys()` — which does not exist and has to be written whatever glyph -is chosen — plus one dashed line and three fill states. No kernel work. It is the same piece of work -as G3 (live preview), and doing them together is what makes the mate card honest. - ---- - -## 8c. The "faceted ridge dome" proposal — built, rendered, judged - -A colleague proposed replacing the flat disc with an **asymmetric low-poly solid**: a faceted -prismatic wedge with a dominant longitudinal ridge that **slopes** from a tall steep back to a long -shallow front, plus a male protrusion / female pocket pair with a 0.2 mm clearance. - -It was built rather than discussed. `faceted_ridge_key.scad` (this folder) (6 vertices, 7 faces), -verified as a closed manifold, exported through OpenSCAD, and flat-shaded from five directions with -`render_key.py` / `render_stl.py`. Sheets: `rk-sheet.png`, `cmp-sheet.png`. - -### The verdict: the shape is right, the male/female polarity cue is not - -**It solves F4, decisively.** The grazing view — where the flat disc dies, its quadrant collapsing to -a blob — is the view where this shape is *most* legible: the tall back and long shallow front are -unmistakable in silhouette. At a grazing angle the silhouette IS the information, and this solid's -silhouette is maximally informative there. That is a real, evidence-backed win over what is currently -in the code. - -**Down the mating axis (+Z) it also reads well**, which matters because that is the natural viewing -direction when you are looking at a face you intend to mate. - -**One degenerate view, and it is not the one I predicted.** I expected the ±X views (along the ridge) -to be silhouette-ambiguous, resolved only by shading. Wrong: front and back are clearly *different* — -the front shows several facets, the back is a **single flat featureless triangle**. So they are not -confusable, but the view from directly behind the tall end tells you nothing about roll or slope. -A second blind spot remains untested: from below the base, where the protrusion is hidden behind its -own face. - -**The female half fails, and much harder than expected.** Rendered with flat shading and no outlines — -the honest test, since a viewport draws no black edges — a recessed pocket is *invisible*: iso and -grazing show a plain block with a hairline; straight down the axis shows a **completely blank -rectangle**. The interior faces are lit almost identically to the top face and are occluded by the rim -from most angles. As a polarity cue, male/female therefore works in exactly one direction and returns -nothing in the other. - -> **Conclusion: do not overload shape with all three jobs.** Let the solid carry **verse and roll**, -> where it is excellent, and carry **polarity on a second channel** — colour plus the filled/open head -> that already tested well at 22 px (F2). Drawing the fixed connector as an outline/wireframe of the -> same solid is the variant worth trying; drawing it as a pocket is not. - -### Two premises in the brief are wrong - -**"Avoid curved surfaces to optimise rendering computations / rapid mesh processing."** Not a reason -for a viewport glyph. There are 2–20 connectors on screen, the renderer pushes `GLModel` triangles -directly, and it performs no CSG or mesh processing at all. **The real argument for flat facets is -legibility**: hard normals give distinct value steps between adjacent facets, and the renders confirm -that is exactly what makes the shape readable from an arbitrary angle. Keep the constraint, fix the -justification. (For a *printed* part the original justification is sound for a different reason: flat -facets slice without the stair-stepping a tessellated curve produces.) - -**"0.2 mm clearance for smooth mechanical mating."** Meaningless for a glyph. A symbol mates with -nothing, and every gizmo here is sized in screen pixels via `upp`, so a millimetre tolerance has no -referent. This is the strongest signal that **the brief was written for a physical printed part**, -not for a viewport symbol — as are "scannable" and "mechanical mating". See the open question below. - -### Two defects the build caught that discussion would not have - -1. **The flank quads are not planar.** Written as `[0,3,5,4]` and `[1,4,5,2]` the base edge and the - ridge edge are skew, so the four corners do not share a plane — my own first draft asserted the - opposite in a comment. Left as quads, the tessellator picks the fold direction, the "flat facet" - promise is broken by an unspecified crease, and two exporters can disagree about the shape. Fixed - by triangulating explicitly (7 faces, Euler 6 − 11 + 7 = 2). -2. **The pocket punched through its own plate.** A 4.5 mm key against a 3 mm demo plate gives a - through-hole, not a pocket. Minimum stock = height + clearance + pocket depth + a wall. - -Also worth recording: the first female render was misleading because the debug renderer outlined -*every* triangle, so a flat top face triangulated by CGAL looked like a faceted dome. The instrument -lied before the geometry did. Conclusions were only drawn after outlines were removed. - -### Second opinion, and the one disagreement worth resolving - -Kimi reviewed the proposal independently and **rejected it for the viewport**. It agreed on the two -wrong premises, agreed the female pocket is unreadable, and added the useful framing that a -screen-constant symbol and a model-constant part feature are two different design spaces that cannot -be served by one geometry. It also noted correctly that there is **no single scalar** that removes -ambiguity from every view: you need one asymmetry in the base plane (for top-down roll) and one out -of plane (the ridge slope, for front/back). Our base is scalene, so it has both. - -Its central objection was numeric and testable: *"at 22 px with 6–8 facets each facet is 3–7 px wide, -that is at the aliasing limit … minimum useful size is roughly 32–48 px, which is not compatible with -a 22 px screen-constant symbol."* My own renders were ~300 px, so the claim was unaddressed by my -evidence and would have killed the concept if true. - -**Rendered at 22, 32 and 48 px (`size-test.png`), it is false for this shape.** At 22 px all three -views still read: the grazing view shows the tall back and shallow front unmistakably, and the -down-axis view keeps a strong dark/light split. The reason Kimi's arithmetic does not apply is that -this solid presents only **four or five large facets with high value contrast**, not eight small ones — -the silhouette does most of the work, and silhouettes survive downsampling far better than facet -detail does. - -*Honest limit on that result:* the test renderer has no anti-aliasing, no perspective, one directional -light, and no background. Readable at 22 px against white is not the same as readable at 22 px on top -of a shaded gold part next to the move gizmo. That case still needs the rig. - -**Where I do not follow Kimi:** its recommendation is to **billboard** the existing flat glyph so it -never turns edge-on. That kills F4 by construction, but a billboarded frame cannot show the frame's -orientation *in place* — which is the entire reason the disc is a disc and not a dot — and it is what -no surveyed CAD system does; Onshape, Fusion and FreeCAD all draw the frame in the geometry. Worth -prototyping as an option, not worth adopting on argument. - -### Open question for Tommaso - -**Is this a viewport glyph or a printable alignment feature?** The vertex logic is identical either -way; only the units and the clearance change, and the `.scad` file states both readings. But the -answer decides whether `clr`/`depth` are real millimetres or meaningless, and whether the geometry -scales with the model or stays screen-constant. The brief's own language points at "physical", the -conversation it arrived in points at "glyph". - ---- - -## 9. Decisions for you - -**D1 — Invert the default direction to Facing?** [DEVIATION, R5] -It changes the meaning of every stored document containing a mate. Options: (a) invert and migrate, -writing `direction=Aligned` where `mate_flip` was false; (b) invert only for new mates and store -`direction` explicitly from now on. (b) is safer and costs one field. Note this project has taken one -such semantic hit knowingly before — the `en4` fix — and the golden fixture survived, so the -migration path is a known quantity. **If G3 (live preview) lands first, this matters much less.** - -**D2 — How far to take origin candidates?** [R9] -Four kinds is the Fusion-aligned recommendation. Two (face centroid + arc centre) would cover "sit on -a face" and "go down a hole" — most printed-part assembly — at a third of the work. Where do you want -to stop? - -**D3 — Ball mate: in or out?** -In four of five frame-based systems, so including it is the aligned choice. Out is defensible for -printable mechanical parts. Cheap either way — align origins, leave orientation free. Kimi's review -argued **out**: a true ball joint is hard to print and hard to use without a roll reference, and a -Fastened connector at the ball centre approximates it. - -**D3a — Should Planar be dropped?** [dissent worth recording] -Kimi's independent review recommended **removing Planar** and shipping four types, on the grounds that -"slide on a flat surface" is rarely how printed mechanisms work — you usually want a rail or a hinge — -and that Planar is the type most likely to confuse a user who expected "put this flat on that" and got -a part free to slide. It further ranked the honest minimum as **three**: Fastened, Revolute, Slider, -with Cylindrical useful and decomposable. -**I do not agree, and the reason is alignment.** Planar appears in every frame-based system surveyed, -it is a genuine lower pair, it is already implemented and tested, and removing it is a document-format -change made in exchange for nothing. The confusion Kimi names is real but it is a *feedback* problem — -it is exactly what R17 (show the DOF budget) and R13 (say that free DOF are preserved) exist to fix. -Recorded here because it is a legitimate reading of the same evidence and the call is yours. - -**D4 — Is refusing a second mate per body acceptable?** [DEVIATION, R11 — the big one] -It is the honest consequence of having no solver, and it is what makes the tool predictable. But **no -mainstream system behaves this way**, so it is the point where an experienced user's intuition will -break. It means a part cannot be constrained by two independent relationships — "in this hole *and* -resting on this shoulder" must be expressed by placing one connector correctly rather than by two -mates. If that trade is unacceptable, the answer is a solver, and the scope of this document changes -entirely. - -There is a strong argument that the trade is not merely acceptable but *correct for this product*: -the Design tab lives inside a slicer, and most of its users are positioning parts for printing rather -than building working mechanisms. For layout-and-export, tree-order composition is genuinely enough, -and adding a solver to look like Onshape would buy complexity nobody asked for. The rule to publish is -then simple and defensible: **one mate per moving body, acyclic, no relations between mates** — with -R18's loud refusals carrying the honesty. - ---- - -## Sources - -**Onshape** — [Mate Connector](https://cad.onshape.com/help/Content/PartStudio/mate_connector.htm) · -[Mates](https://cad.onshape.com/help/Content/Assembly/mates.htm) · -[Fastened](https://cad.onshape.com/help/Content/Assembly/fastened_mate.htm) · -[Revolute](https://cad.onshape.com/help/Content/Assembly/revolute_mate.htm) · -[Slider](https://cad.onshape.com/help/Content/Assembly/slider_mate.htm) · -[Cylindrical](https://cad.onshape.com/help/Content/Assembly/cylindrical_mate.htm) · -[Planar](https://cad.onshape.com/help/Content/Assembly/planar_mate.htm) · -[Ball](https://cad.onshape.com/help/Content/Assembly/ball_mate.htm) · -[Parallel](https://cad.onshape.com/help/Content/Assembly/parallel_mate.htm) · -[Tangent](https://cad.onshape.com/help/Content/Assembly/tangent_mate.htm) · -[Pin Slot](https://cad.onshape.com/help/Content/Assembly/pin_slot_mate.htm) · -[5 things you can do with mate connectors in Part Studios](https://www.onshape.com/en/resource-center/tech-tips/tech-tip-5-things-you-can-do-with-mate-connectors-in-onshape-part-studios) - -**Onshape forum** — [The concept behind Mates Z Axes](https://forum.onshape.com/discussion/22828/the-concept-behind-mates-z-axes) (C1/D3) · -[Implicit mate connectors act differently than explicit ones](https://forum.onshape.com/discussion/15736/implicit-mate-connectors-act-differently-than-explicit-ones) (C4) · -[Efficiently set mate connectors](https://forum.onshape.com/discussion/13133/efficiently-set-mate-connectors) - -**Fusion 360** — [Joint types](https://help.autodesk.com/cloudhelp/ENU/Fusion-Assemble/files/GUID-8818AE31-958A-4A59-989B-9875A174C67A.htm) · -[Joint origins](https://help.autodesk.com/view/fusion360/ENU/?guid=ASM-JOINT-ORIGIN) · -[Joints vs. Mates in Fusion](https://www.autodesk.com/products/fusion-360/blog/joints-mates-moving-fusion/) · -[Joint tips — snap points and Ctrl cycling](https://mgfx.co.za/blog/engineering-manufacturing-design/fusion-360-joint-tips/) - -**Inventor** — [Create Joints Reference](https://help.autodesk.com/cloudhelp/2026/ENU/Inventor-Help/files/GUID-6AA68E8F-7C97-4806-8483-3941DE915E70.htm) · -[Use Joint to define and manage relationships](https://knowledge.autodesk.com/support/inventor-products/learn-explore/caas/CloudHelp/cloudhelp/2014/ENU/Inventor/files/GUID-21DC3336-5C51-42C1-90FB-4299CD66E0C6-htm.html) (type inference, D2) - -**FreeCAD 1.0** — [Assembly Workbench](https://wiki.freecad.org/Assembly_Workbench) · -[Fixed Joint properties](https://wiki.freecad.org/Assembly_CreateJointFixed) - -**Creo** — [About Predefined Constraint Sets](https://support.ptc.com/help/creo/creo_pma/r12/usascii/assembly/asm/About_Predefined_Constraint_Sets.html) - -**Siemens NX** — [Assembly constraints](https://learnnx.com/lesson/siemens-nx-assemblies-assembly-constraints/) - -**SOLIDWORKS** — [Mate References](https://help.solidworks.com/2025/English/SolidWorks/sldworks/c_Mate_References_Overview_SWassy.htm) · -[Creating and using mate references](https://blogs.solidworks.com/tech/2019/07/creating-and-using-mate-references.html) - -**Theory** — [Hervé, The Lie group of rigid body displacements, a fundamental tool for mechanism design](https://www.sciencedirect.com/science/article/abs/pii/S0094114X98000512) · -[Joint kinematics — the six lower pairs and their DOF](https://erc-bpgc.github.io/handbook/mechanical/Joint%20Kinematics/) · -[ISO 10303-105 — Kinematics (STEP integrated resource)](https://www.iso.org/standard/78589.html) - -**Internal** — `en4` (closed 2026-07-26, fixes C2 here) · `CadDocument.cpp:1669` -`datum_frame` · `CadDocument.cpp:2961` `apply_mate` · `CadDocument.cpp:1302` `add_mate` - -**Second opinion** — an independent review by Kimi Code (2026-08-05) contributed the -vendors-ship-both caveat (§1), the explicit-dropdown option for origin choice (D1), the expanded -refusal list (R11a), the retrofit list (§8), and the dissents recorded at D3/D3a. One of its claims — -that Onshape mandates *"exactly one Mate between any two instances"* — **was checked against the -source and is wrong**; the correction is recorded at R11 because it is a misreading that would -otherwise turn our largest deviation into a false agreement. diff --git a/docs/CAD/design/mate-connectors/bear-01-view.png b/docs/CAD/design/mate-connectors/bear-01-view.png deleted file mode 100644 index eb57aaeefe..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-01-view.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-02-view.png b/docs/CAD/design/mate-connectors/bear-02-view.png deleted file mode 100644 index 46b6d834fa..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-02-view.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-02-zoom.png b/docs/CAD/design/mate-connectors/bear-02-zoom.png deleted file mode 100644 index 437adaee9d..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-02-zoom.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-flat.png b/docs/CAD/design/mate-connectors/bear-flat.png deleted file mode 100644 index 16375b9d5c..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-flat.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-sil-cmp.png b/docs/CAD/design/mate-connectors/bear-sil-cmp.png deleted file mode 100644 index eb2f283f95..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-sil-cmp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear-sil.png b/docs/CAD/design/mate-connectors/bear-sil.png deleted file mode 100644 index 2b6e51067e..0000000000 Binary files a/docs/CAD/design/mate-connectors/bear-sil.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/bear_glyph_table.h b/docs/CAD/design/mate-connectors/bear_glyph_table.h deleted file mode 100644 index c26631e7e0..0000000000 --- a/docs/CAD/design/mate-connectors/bear_glyph_table.h +++ /dev/null @@ -1,30 +0,0 @@ -// Emitted by doc/design/mate-connectors/emit_glyph_table.py from bear.step — do not hand-edit. -// Normalised to the part's bounding span and centred: the renderer scales by one radius. -static const Vec2d kBearOutline[] = { // 12 verts, RDP eps 0.030, CCW - {+0.3842, +0.3294}, {+0.3156, +0.4002}, {+0.2424, +0.3294}, - {-0.2524, +0.3294}, {-0.3377, +0.3877}, {-0.3693, +0.3298}, - {-0.3256, +0.2631}, {-0.4893, -0.3337}, {-0.3960, -0.4002}, - {+0.4151, -0.4002}, {+0.5000, -0.3154}, {+0.3156, +0.2631}, -}; -static const Vec2d kBearChin[] = { // the CHIN BAR, flat. The muzzle is relief — see kBearCrest. - {-0.2682, -0.3578}, {+0.2628, -0.3578}, {+0.2237, -0.1786}, -}; -// {cx, cy, r}: two eyes, then the cheek dot that carries handedness (wi3z). -static const Vec3d kBearMarks[] = { - {-0.1997, +0.1760, +0.0590}, - {+0.1947, +0.1760, +0.0590}, - {+0.2797, +0.0760, +0.0380}, -}; -// THE MUZZLE, lifted off the mesh: a tapered wedge, base quad + crest edge, 6 facets. -// This is the only feature standing along +Z and the only one still legible edge-on. -static const double kBearPlateZ = +0.0360; -static const Vec2d kBearSnoutBase[] = { // CCW from the nose end - {-0.0727, -0.2417}, - {+0.0630, -0.2417}, - {+0.0259, +0.1939}, - {-0.0356, +0.1939}, -}; -static const Vec3d kBearCrest[] = { // nose (tall) -> tail (short) - {-0.0048, -0.1793, +0.2073}, - {-0.0048, +0.1605, +0.1279}, -}; diff --git a/docs/CAD/design/mate-connectors/bear_mesh.json b/docs/CAD/design/mate-connectors/bear_mesh.json deleted file mode 100644 index 4bfb6aa361..0000000000 --- a/docs/CAD/design/mate-connectors/bear_mesh.json +++ /dev/null @@ -1 +0,0 @@ -{"v": [[-36.7146, 0.0, -1.7146], [-36.0624, 0.0, -1.152], [-36.5065, 0.0, -1.5165], [-36.2889, 0.0, -1.3288], [-39.9409, 0.0, -4.9818], [-40.1196, 0.0, -5.2115], [-39.751, 0.0, -4.7612], [-39.5503, 0.0, -4.5503], [-35.8275, 0.0, -0.9866], [-35.3348, 0.0, -0.6912], [-35.5848, 0.0, -0.8329], [-40.4417, 0.0, -5.6962], [-40.5842, 0.0, -5.95], [-40.2867, 0.0, -5.4499], [-35.0781, 0.0, -0.5621], [-40.714, 0.0, -6.2105], [-34.5473, 0.0, -0.3422], [-34.8154, 0.0, -0.4456], [-40.8307, 0.0, -6.4772], [-40.934, 0.0, -6.7493], [-41.0236, 0.0, -7.0262], [-33.9976, 0.0, -0.1754], [-34.2745, 0.0, -0.2521], [-41.161, 0.0, -7.5917], [-41.2085, 0.0, -7.8789], [-41.0994, 0.0, -7.3072], [-33.149, 0.0, -0.0282], [-33.7172, 0.0, -0.1125], [-33.4341, 0.0, -0.0634], [-32.8624, 0.0, -0.0071], [-32.5752, 0.0, -0.0], [-41.2544, 0.0, -9.0404], [-41.2298, 0.0, -9.3304], [-41.2646, 0.0, -8.7495], [-41.2604, 0.0, -8.4585], [-41.2417, 0.0, -8.168], [-41.1908, 0.0, -9.6189], [-41.1374, 0.0, -9.905], [-41.07, 0.0, -10.1881], [-40.9885, 0.0, -10.4676], [-21.9255, 0.0, -9.1038], [-21.9255, 0.0, -3.5345], [-20.0463, 0.0, -44.6525], [-19.8744, 0.0, -44.4763], [-19.694, 0.0, -44.309], [-20.2091, 0.0, -44.837], [-19.5055, 0.0, -44.1508], [-20.3625, 0.0, -45.0294], [-19.3094, 0.0, -44.0022], [-20.5062, 0.0, -45.2292], [-19.106, 0.0, -43.8635], [-20.6397, 0.0, -45.436], [-18.896, 0.0, -43.7352], [-20.7628, 0.0, -45.6491], [-18.6799, 0.0, -43.6175], [-20.875, 0.0, -45.8681], [-18.4582, 0.0, -43.5108], [-20.9762, 0.0, -46.0924], [-18.2314, 0.0, -43.4152], [-21.0662, 0.0, -46.3215], [-18.0002, 0.0, -43.331], [-17.765, 0.0, -43.2585], [-17.5265, 0.0, -43.1977], [22.3077, 0.0, -3.5345], [-17.2853, 0.0, -43.149], [-17.042, 0.0, -43.1123], [-16.7971, 0.0, -43.0878], [-16.5513, 0.0, -43.0755], [-16.3052, 0.0, -43.0755], [-16.0594, 0.0, -43.0878], [-15.8146, 0.0, -43.1123], [-15.5712, 0.0, -43.149], [-15.33, 0.0, -43.1977], [-0.0, 0.0, -9.1038], [-15.0915, 0.0, -43.2585], [-14.8564, 0.0, -43.331], [-21.2112, 0.0, -49.2274], [-26.7105, 0.0, -55.2632], [-21.1445, 0.0, -49.4643], [-21.2659, 0.0, -48.9875], [-21.3087, 0.0, -48.7451], [-21.3393, 0.0, -48.5009], [-21.3577, 0.0, -48.2555], [-21.3638, 0.0, -48.0095], [-21.3577, 0.0, -47.7635], [-21.3393, 0.0, -47.5181], [-21.3087, 0.0, -47.2739], [-21.2659, 0.0, -47.0316], [-21.2112, 0.0, -46.7916], [-21.1445, 0.0, -46.5547], [-21.0662, 0.0, -49.6976], [-14.6251, 0.0, -43.4152], [-20.9762, 0.0, -49.9266], [-14.3984, 0.0, -43.5108], [-20.875, 0.0, -50.151], [-14.1766, 0.0, -43.6175], [-20.7628, 0.0, -50.37], [-13.9605, 0.0, -43.7352], [-20.6397, 0.0, -50.5831], [-13.7505, 0.0, -43.8635], [-20.5062, 0.0, -50.7898], [-13.5472, 0.0, -44.0022], [-20.3625, 0.0, -50.9896], [-13.351, 0.0, -44.1508], [-20.2091, 0.0, -51.182], [-13.1625, 0.0, -44.309], [-20.0463, 0.0, -51.3665], [-19.8744, 0.0, -51.5427], [-19.694, 0.0, -51.7101], [-19.5055, 0.0, -51.8683], [-19.3094, 0.0, -52.0169], [-19.106, 0.0, -52.1555], [35.0, 0.0, 0.0], [19.0522, 0.0, -18.4636], [16.4743, 0.0, -9.1399], [-27.6672, 0.0, -65.6993], [-27.6141, 0.0, -65.7466], [-27.7179, 0.0, -65.6494], [-27.5588, 0.0, -65.7913], [-27.4419, 0.0, -65.8722], [-27.3806, 0.0, -65.9082], [-27.5013, 0.0, -65.8332], [-27.3177, 0.0, -65.9412], [-27.2531, 0.0, -65.9711], [-27.1872, 0.0, -65.9978], [-27.1201, 0.0, -66.0212], [-27.0519, 0.0, -66.0413], [-26.9828, 0.0, -66.058], [-26.9129, 0.0, -66.0713], [-26.8425, 0.0, -66.0811], [-26.7007, 0.0, -66.0904], [-26.7717, 0.0, -66.0875], [-26.6296, 0.0, -66.0899], [-26.4879, 0.0, -66.0782], [-26.4177, 0.0, -66.0672], [-26.5586, 0.0, -66.0858], [-26.3481, 0.0, -66.0528], [-26.2792, 0.0, -66.035], [-26.2114, 0.0, -66.0138], [-26.1446, 0.0, -65.9893], [-26.0792, 0.0, -65.9615], [-26.0151, 0.0, -65.9306], [-25.9527, 0.0, -65.8966], [-25.892, 0.0, -65.8595], [-25.8332, 0.0, -65.8196], [-25.7765, 0.0, -65.7767], [-25.7219, 0.0, -65.7312], [-25.6696, 0.0, -65.683], [-28.9439, 0.0, -64.3825], [-29.1102, 0.0, -64.202], [-29.2675, 0.0, -64.0136], [-29.4153, 0.0, -63.8176], [-29.5533, 0.0, -63.6147], [-29.6811, 0.0, -63.4052], [-29.7986, 0.0, -63.1898], [-29.9053, 0.0, -62.9688], [-30.0011, 0.0, -62.7428], [-30.0856, 0.0, -62.5124], [-30.1588, 0.0, -62.2782], [-30.2204, 0.0, -62.0406], [-30.2702, 0.0, -61.8003], [-30.3082, 0.0, -61.5579], [-30.3342, 0.0, -61.3138], [-30.3483, 0.0, -61.0688], [-30.3503, 0.0, -60.8234], [-30.3402, 0.0, -60.5782], [-30.3182, 0.0, -60.3338], [-30.2841, 0.0, -60.0908], [-30.2382, 0.0, -59.8497], [-30.1805, 0.0, -59.6111], [-30.1112, 0.0, -59.3757], [-30.0304, 0.0, -59.144], [-29.9383, 0.0, -58.9165], [-29.8352, 0.0, -58.6938], [-29.7213, 0.0, -58.4764], [-29.5969, 0.0, -58.2649], [-13.7505, 0.0, -52.1555], [-20.6129, 0.0, -60.7895], [-13.5472, 0.0, -52.0169], [-13.9605, 0.0, -52.2838], [-14.1766, 0.0, -52.4015], [-14.3984, 0.0, -52.5083], [-14.6251, 0.0, -52.6039], [-14.8564, 0.0, -52.688], [-15.0915, 0.0, -52.7606], [-15.33, 0.0, -52.8213], [-15.5712, 0.0, -52.8701], [-15.8146, 0.0, -52.9067], [-16.0594, 0.0, -52.9312], [-16.3052, 0.0, -52.9435], [-16.5513, 0.0, -52.9435], [-16.7971, 0.0, -52.9312], [-17.042, 0.0, -52.9067], [-17.2853, 0.0, -52.8701], [-17.5265, 0.0, -52.8213], [-17.765, 0.0, -52.7606], [-18.0002, 0.0, -52.688], [-18.2314, 0.0, -52.6039], [-18.4582, 0.0, -52.5083], [-18.6799, 0.0, -52.4015], [-18.896, 0.0, -52.2838], [-29.4622, 0.0, -58.0598], [-29.3176, 0.0, -57.8615], [-29.1635, 0.0, -57.6705], [-29.0002, 0.0, -57.4873], [-28.828, 0.0, -57.3124], [42.0711, 0.0, -7.0711], [-12.9821, 0.0, -44.4763], [12.9821, 0.0, -44.4763], [-12.8103, 0.0, -44.6525], [12.8103, 0.0, -44.6525], [-12.6474, 0.0, -44.837], [13.1625, 0.0, -44.309], [12.6474, 0.0, -44.837], [13.351, 0.0, -44.1508], [-12.494, 0.0, -45.0294], [12.494, 0.0, -45.0294], [13.5472, 0.0, -44.0022], [-12.3504, 0.0, -45.2292], [12.3504, 0.0, -45.2292], [-12.2168, 0.0, -45.436], [13.7505, 0.0, -43.8635], [-12.0938, 0.0, -45.6491], [12.2168, 0.0, -45.436], [13.9605, 0.0, -43.7352], [12.0938, 0.0, -45.6491], [14.1766, 0.0, -43.6175], [-11.9815, 0.0, -45.8681], [11.9815, 0.0, -45.8681], [14.3984, 0.0, -43.5108], [-11.8803, 0.0, -46.0924], [11.8803, 0.0, -46.0924], [14.6251, 0.0, -43.4152], [11.7904, 0.0, -46.3215], [-11.7904, 0.0, -46.3215], [-11.712, 0.0, -46.5547], [14.8564, 0.0, -43.331], [11.712, 0.0, -46.5547], [15.0915, 0.0, -43.2585], [-11.6454, 0.0, -46.7916], [11.6454, 0.0, -46.7916], [15.33, 0.0, -43.1977], [-11.5906, 0.0, -47.0316], [11.5906, 0.0, -47.0316], [15.5712, 0.0, -43.149], [-11.5479, 0.0, -47.2739], [11.5479, 0.0, -47.2739], [15.8146, 0.0, -43.1123], [-11.5173, 0.0, -47.5181], [11.5173, 0.0, -47.5181], [16.0594, 0.0, -43.0878], [11.4989, 0.0, -47.7635], [-11.4989, 0.0, -47.7635], [16.3052, 0.0, -43.0755], [11.4928, 0.0, -48.0095], [-11.4928, 0.0, -48.0095], [16.5513, 0.0, -43.0755], [-11.4989, 0.0, -48.2555], [11.4989, 0.0, -48.2555], [-11.5173, 0.0, -48.5009], [16.7971, 0.0, -43.0878], [11.5173, 0.0, -48.5009], [-11.5479, 0.0, -48.7451], [17.042, 0.0, -43.1123], [11.5479, 0.0, -48.7451], [17.2853, 0.0, -43.149], [11.5906, 0.0, -48.9875], [-11.5906, 0.0, -48.9875], [17.5265, 0.0, -43.1977], [11.6454, 0.0, -49.2274], [-11.6454, 0.0, -49.2274], [17.765, 0.0, -43.2585], [-11.712, 0.0, -49.4643], [11.712, 0.0, -49.4643], [-11.7904, 0.0, -49.6976], [18.0002, 0.0, -43.331], [11.7904, 0.0, -49.6976], [18.2314, 0.0, -43.4152], [-11.8803, 0.0, -49.9266], [11.8803, 0.0, -49.9266], [18.4582, 0.0, -43.5108], [-11.9815, 0.0, -50.151], [11.9815, 0.0, -50.151], [18.6799, 0.0, -43.6175], [-12.0938, 0.0, -50.37], [12.0938, 0.0, -50.37], [18.896, 0.0, -43.7352], [-12.2168, 0.0, -50.5831], [12.2168, 0.0, -50.5831], [-12.3504, 0.0, -50.7898], [19.106, 0.0, -43.8635], [12.3504, 0.0, -50.7898], [19.3094, 0.0, -44.0022], [-12.494, 0.0, -50.9896], [12.494, 0.0, -50.9896], [19.5055, 0.0, -44.1508], [-12.6474, 0.0, -51.182], [12.6474, 0.0, -51.182], [-12.8103, 0.0, -51.3665], [19.694, 0.0, -44.309], [12.8103, 0.0, -51.3665], [-12.9821, 0.0, -51.5427], [19.8744, 0.0, -44.4763], [-13.1625, 0.0, -51.7101], [12.9821, 0.0, -51.5427], [20.0463, 0.0, -44.6525], [13.1625, 0.0, -51.7101], [20.2091, 0.0, -44.837], [13.351, 0.0, -51.8683], [-13.351, 0.0, -51.8683], [20.3625, 0.0, -45.0294], [13.5472, 0.0, -52.0169], [20.5062, 0.0, -45.2292], [20.6397, 0.0, -45.436], [20.7628, 0.0, -45.6491], [20.875, 0.0, -45.8681], [20.9762, 0.0, -46.0924], [20.6129, 0.0, -60.7895], [18.896, 0.0, -52.2838], [19.106, 0.0, -52.1555], [18.6799, 0.0, -52.4015], [18.4582, 0.0, -52.5083], [18.2314, 0.0, -52.6039], [18.0002, 0.0, -52.688], [17.765, 0.0, -52.7606], [17.5265, 0.0, -52.8213], [17.2853, 0.0, -52.8701], [17.042, 0.0, -52.9067], [16.7971, 0.0, -52.9312], [16.5513, 0.0, -52.9435], [16.3052, 0.0, -52.9435], [16.0594, 0.0, -52.9312], [15.8146, 0.0, -52.9067], [15.5712, 0.0, -52.8701], [15.33, 0.0, -52.8213], [15.0915, 0.0, -52.7606], [14.8564, 0.0, -52.688], [14.6251, 0.0, -52.6039], [14.3984, 0.0, -52.5083], [14.1766, 0.0, -52.4015], [13.9605, 0.0, -52.2838], [13.7505, 0.0, -52.1555], [26.7105, 0.0, -55.2632], [21.3577, 0.0, -48.2555], [21.3638, 0.0, -48.0095], [21.3393, 0.0, -48.5009], [21.3087, 0.0, -48.7451], [21.2659, 0.0, -48.9875], [21.2112, 0.0, -49.2274], [21.1445, 0.0, -49.4643], [21.0662, 0.0, -49.6976], [20.9762, 0.0, -49.9266], [20.875, 0.0, -50.151], [20.7628, 0.0, -50.37], [20.6397, 0.0, -50.5831], [20.5062, 0.0, -50.7898], [20.3625, 0.0, -50.9896], [20.2091, 0.0, -51.182], [20.0463, 0.0, -51.3665], [19.8744, 0.0, -51.5427], [19.694, 0.0, -51.7101], [21.0662, 0.0, -46.3215], [19.5055, 0.0, -51.8683], [21.1445, 0.0, -46.5547], [19.3094, 0.0, -52.0169], [21.2112, 0.0, -46.7916], [21.2659, 0.0, -47.0316], [21.3087, 0.0, -47.2739], [21.3393, 0.0, -47.5181], [21.3577, 0.0, -47.7635], [26.7105, 0.0, -66.6904], [32.4211, 0.0, -60.7895], [-40.1196, 3.0, -5.2115], [-39.9409, 3.0, -4.9818], [-39.751, 3.0, -4.7612], [-39.5503, 3.0, -4.5503], [-35.3348, 3.0, -0.6912], [-35.8275, 3.0, -0.9866], [-35.5848, 3.0, -0.8329], [-36.0624, 3.0, -1.152], [-40.714, 3.0, -6.2105], [-40.5842, 3.0, -5.95], [-40.4417, 3.0, -5.6962], [-40.2867, 3.0, -5.4499], [-34.5473, 3.0, -0.3422], [-35.0781, 3.0, -0.5621], [-34.8154, 3.0, -0.4456], [-41.0236, 3.0, -7.0262], [-40.934, 3.0, -6.7493], [-40.8307, 3.0, -6.4772], [-33.9976, 3.0, -0.1754], [-34.2745, 3.0, -0.2521], [-36.5065, 3.0, -1.5165], [-36.2889, 3.0, -1.3288], [-41.2085, 3.0, -7.8789], [-41.161, 3.0, -7.5917], [-41.0994, 3.0, -7.3072], [-33.149, 3.0, -0.0282], [-33.7172, 3.0, -0.1125], [-33.4341, 3.0, -0.0634], [-36.7146, 3.0, -1.7146], [-41.2417, 3.0, -8.168], [-32.8624, 3.0, -0.0071], [-32.5752, 3.0, -0.0], [-41.2298, 3.0, -9.3304], [-41.2544, 3.0, -9.0404], [-41.2646, 3.0, -8.7495], [-41.2604, 3.0, -8.4585], [-41.07, 3.0, -10.1881], [-41.1374, 3.0, -9.905], [-41.1908, 3.0, -9.6189], [-40.9885, 3.0, -10.4676], [-21.9255, 3.0, -9.1038], [-21.9255, 3.0, -3.5345], [5.6569, 3.0, -13.2042], [-5.6569, 3.0, -13.2042], [-0.0, 3.0, -9.1038], [-20.0463, 3.0, -44.6525], [-19.8744, 3.0, -44.4763], [-19.694, 3.0, -44.309], [-20.2091, 3.0, -44.837], [-19.5055, 3.0, -44.1508], [-20.3625, 3.0, -45.0294], [-19.3094, 3.0, -44.0022], [-20.5062, 3.0, -45.2292], [-19.106, 3.0, -43.8635], [-20.6397, 3.0, -45.436], [-18.896, 3.0, -43.7352], [-20.7628, 3.0, -45.6491], [-18.6799, 3.0, -43.6175], [-20.875, 3.0, -45.8681], [-18.4582, 3.0, -43.5108], [-20.9762, 3.0, -46.0924], [-18.2314, 3.0, -43.4152], [-21.0662, 3.0, -46.3215], [-18.0002, 3.0, -43.331], [-17.765, 3.0, -43.2585], [16.4743, 3.0, -9.1399], [-17.5265, 3.0, -43.1977], [22.3077, 3.0, -3.5345], [-17.2853, 3.0, -43.149], [-17.042, 3.0, -43.1123], [-16.7971, 3.0, -43.0878], [-16.5513, 3.0, -43.0755], [-16.3052, 3.0, -43.0755], [-16.0594, 3.0, -43.0878], [-15.8146, 3.0, -43.1123], [-15.5712, 3.0, -43.149], [-15.33, 3.0, -43.1977], [-15.0915, 3.0, -43.2585], [-14.8564, 3.0, -43.331], [-26.7105, 3.0, -55.2632], [-21.2112, 3.0, -49.2274], [-21.1445, 3.0, -49.4643], [-21.2659, 3.0, -48.9875], [-21.3087, 3.0, -48.7451], [-21.3393, 3.0, -48.5009], [-21.3577, 3.0, -48.2555], [-21.3638, 3.0, -48.0095], [-21.3577, 3.0, -47.7635], [-21.3393, 3.0, -47.5181], [-21.3087, 3.0, -47.2739], [-21.2659, 3.0, -47.0316], [-21.2112, 3.0, -46.7916], [-21.1445, 3.0, -46.5547], [-21.0662, 3.0, -49.6976], [-14.6251, 3.0, -43.4152], [-20.9762, 3.0, -49.9266], [-14.3984, 3.0, -43.5108], [-20.875, 3.0, -50.151], [-14.1766, 3.0, -43.6175], [-20.7628, 3.0, -50.37], [-13.9605, 3.0, -43.7352], [-20.6397, 3.0, -50.5831], [-13.7505, 3.0, -43.8635], [-20.5062, 3.0, -50.7898], [-13.5472, 3.0, -44.0022], [-20.3625, 3.0, -50.9896], [-13.351, 3.0, -44.1508], [-20.2091, 3.0, -51.182], [-13.1625, 3.0, -44.309], [-20.0463, 3.0, -51.3665], [-12.9821, 3.0, -44.4763], [-19.8744, 3.0, -51.5427], [-19.694, 3.0, -51.7101], [-19.5055, 3.0, -51.8683], [-19.3094, 3.0, -52.0169], [-19.106, 3.0, -52.1555], [35.0, 3.0, 0.0], [19.0522, 3.0, -18.4636], [-27.6141, 3.0, -65.7466], [-27.6672, 3.0, -65.6993], [-27.7179, 3.0, -65.6494], [-27.5588, 3.0, -65.7913], [-27.3806, 3.0, -65.9082], [-27.4419, 3.0, -65.8722], [-27.5013, 3.0, -65.8332], [-27.2531, 3.0, -65.9711], [-27.3177, 3.0, -65.9412], [-27.1872, 3.0, -65.9978], [-27.0519, 3.0, -66.0413], [-27.1201, 3.0, -66.0212], [-26.9129, 3.0, -66.0713], [-26.9828, 3.0, -66.058], [-26.8425, 3.0, -66.0811], [-26.7007, 3.0, -66.0904], [-26.7717, 3.0, -66.0875], [-26.5586, 3.0, -66.0858], [-26.6296, 3.0, -66.0899], [-26.2792, 3.0, -66.035], [-26.3481, 3.0, -66.0528], [-26.4177, 3.0, -66.0672], [-26.4879, 3.0, -66.0782], [-26.1446, 3.0, -65.9893], [-26.2114, 3.0, -66.0138], [-26.0792, 3.0, -65.9615], [-25.9527, 3.0, -65.8966], [-26.0151, 3.0, -65.9306], [-25.8332, 3.0, -65.8196], [-25.892, 3.0, -65.8595], [-25.7765, 3.0, -65.7767], [-25.6696, 3.0, -65.683], [-25.7219, 3.0, -65.7312], [-28.9439, 3.0, -64.3825], [-29.1102, 3.0, -64.202], [-29.2675, 3.0, -64.0136], [-29.4153, 3.0, -63.8176], [-29.5533, 3.0, -63.6147], [-29.6811, 3.0, -63.4052], [-29.7986, 3.0, -63.1898], [-29.9053, 3.0, -62.9688], [-30.0011, 3.0, -62.7428], [-30.0856, 3.0, -62.5124], [-30.1588, 3.0, -62.2782], [-30.2204, 3.0, -62.0406], [-30.2702, 3.0, -61.8003], [-30.3082, 3.0, -61.5579], [-30.3342, 3.0, -61.3138], [-30.3483, 3.0, -61.0688], [-30.3503, 3.0, -60.8234], [-30.3402, 3.0, -60.5782], [-30.3182, 3.0, -60.3338], [-30.2841, 3.0, -60.0908], [-30.2382, 3.0, -59.8497], [-30.1805, 3.0, -59.6111], [-30.1112, 3.0, -59.3757], [-30.0304, 3.0, -59.144], [-29.9383, 3.0, -58.9165], [-29.8352, 3.0, -58.6938], [-29.7213, 3.0, -58.4764], [-29.5969, 3.0, -58.2649], [-20.6129, 3.0, -60.7895], [-13.9605, 3.0, -52.2838], [-13.7505, 3.0, -52.1555], [-14.1766, 3.0, -52.4015], [-14.3984, 3.0, -52.5083], [-14.6251, 3.0, -52.6039], [-14.8564, 3.0, -52.688], [-15.0915, 3.0, -52.7606], [-15.33, 3.0, -52.8213], [-15.5712, 3.0, -52.8701], [-15.8146, 3.0, -52.9067], [-16.0594, 3.0, -52.9312], [-16.3052, 3.0, -52.9435], [-16.5513, 3.0, -52.9435], [-16.7971, 3.0, -52.9312], [-17.042, 3.0, -52.9067], [-17.2853, 3.0, -52.8701], [-17.5265, 3.0, -52.8213], [-17.765, 3.0, -52.7606], [-18.0002, 3.0, -52.688], [-18.2314, 3.0, -52.6039], [-18.4582, 3.0, -52.5083], [-18.6799, 3.0, -52.4015], [-18.896, 3.0, -52.2838], [-29.4622, 3.0, -58.0598], [-29.3176, 3.0, -57.8615], [-29.1635, 3.0, -57.6705], [-29.0002, 3.0, -57.4873], [-28.828, 3.0, -57.3124], [-2.5595, 3.0, -49.5058], [-11.4989, 3.0, -48.2555], [-11.4928, 3.0, -48.0095], [-11.5173, 3.0, -48.5009], [-11.5479, 3.0, -48.7451], [-11.5906, 3.0, -48.9875], [-11.6454, 3.0, -49.2274], [-11.712, 3.0, -49.4643], [-11.7904, 3.0, -49.6976], [-11.8803, 3.0, -49.9266], [-11.9815, 3.0, -50.151], [-12.8103, 3.0, -44.6525], [-12.0938, 3.0, -50.37], [-12.6474, 3.0, -44.837], [-12.2168, 3.0, -50.5831], [-12.494, 3.0, -45.0294], [-12.3504, 3.0, -50.7898], [-12.3504, 3.0, -45.2292], [-12.494, 3.0, -50.9896], [-12.2168, 3.0, -45.436], [-12.6474, 3.0, -51.182], [-12.0938, 3.0, -45.6491], [-12.8103, 3.0, -51.3665], [-11.9815, 3.0, -45.8681], [-12.9821, 3.0, -51.5427], [-11.8803, 3.0, -46.0924], [-13.1625, 3.0, -51.7101], [-11.7904, 3.0, -46.3215], [-13.351, 3.0, -51.8683], [-11.712, 3.0, -46.5547], [-13.5472, 3.0, -52.0169], [-11.6454, 3.0, -46.7916], [-11.5906, 3.0, -47.0316], [-11.5479, 3.0, -47.2739], [-11.5173, 3.0, -47.5181], [-11.4989, 3.0, -47.7635], [42.0711, 3.0, -7.0711], [2.5595, 3.0, -49.5058], [12.9821, 3.0, -44.4763], [12.8103, 3.0, -44.6525], [13.1625, 3.0, -44.309], [12.6474, 3.0, -44.837], [13.351, 3.0, -44.1508], [12.494, 3.0, -45.0294], [13.5472, 3.0, -44.0022], [12.3504, 3.0, -45.2292], [13.7505, 3.0, -43.8635], [12.2168, 3.0, -45.436], [13.9605, 3.0, -43.7352], [12.0938, 3.0, -45.6491], [14.1766, 3.0, -43.6175], [11.9815, 3.0, -45.8681], [14.3984, 3.0, -43.5108], [11.8803, 3.0, -46.0924], [14.6251, 3.0, -43.4152], [11.7904, 3.0, -46.3215], [14.8564, 3.0, -43.331], [11.712, 3.0, -46.5547], [15.0915, 3.0, -43.2585], [11.6454, 3.0, -46.7916], [15.33, 3.0, -43.1977], [11.5906, 3.0, -47.0316], [15.5712, 3.0, -43.149], [11.5479, 3.0, -47.2739], [15.8146, 3.0, -43.1123], [11.5173, 3.0, -47.5181], [16.0594, 3.0, -43.0878], [11.4989, 3.0, -47.7635], [16.3052, 3.0, -43.0755], [11.4928, 3.0, -48.0095], [16.5513, 3.0, -43.0755], [11.4989, 3.0, -48.2555], [16.7971, 3.0, -43.0878], [11.5173, 3.0, -48.5009], [17.042, 3.0, -43.1123], [11.5479, 3.0, -48.7451], [17.2853, 3.0, -43.149], [11.5906, 3.0, -48.9875], [17.5265, 3.0, -43.1977], [11.6454, 3.0, -49.2274], [17.765, 3.0, -43.2585], [11.712, 3.0, -49.4643], [18.0002, 3.0, -43.331], [11.7904, 3.0, -49.6976], [18.2314, 3.0, -43.4152], [11.8803, 3.0, -49.9266], [18.4582, 3.0, -43.5108], [11.9815, 3.0, -50.151], [18.6799, 3.0, -43.6175], [12.0938, 3.0, -50.37], [18.896, 3.0, -43.7352], [12.2168, 3.0, -50.5831], [19.106, 3.0, -43.8635], [12.3504, 3.0, -50.7898], [19.3094, 3.0, -44.0022], [12.494, 3.0, -50.9896], [19.5055, 3.0, -44.1508], [12.6474, 3.0, -51.182], [19.694, 3.0, -44.309], [12.8103, 3.0, -51.3665], [19.8744, 3.0, -44.4763], [12.9821, 3.0, -51.5427], [20.0463, 3.0, -44.6525], [13.1625, 3.0, -51.7101], [20.2091, 3.0, -44.837], [13.351, 3.0, -51.8683], [20.3625, 3.0, -45.0294], [13.5472, 3.0, -52.0169], [20.5062, 3.0, -45.2292], [13.7505, 3.0, -52.1555], [20.6397, 3.0, -45.436], [20.7628, 3.0, -45.6491], [20.875, 3.0, -45.8681], [20.9762, 3.0, -46.0924], [20.6129, 3.0, -60.7895], [13.9605, 3.0, -52.2838], [14.1766, 3.0, -52.4015], [14.3984, 3.0, -52.5083], [14.6251, 3.0, -52.6039], [14.8564, 3.0, -52.688], [15.0915, 3.0, -52.7606], [15.33, 3.0, -52.8213], [15.5712, 3.0, -52.8701], [15.8146, 3.0, -52.9067], [16.0594, 3.0, -52.9312], [16.3052, 3.0, -52.9435], [16.5513, 3.0, -52.9435], [16.7971, 3.0, -52.9312], [17.042, 3.0, -52.9067], [17.2853, 3.0, -52.8701], [17.5265, 3.0, -52.8213], [17.765, 3.0, -52.7606], [18.0002, 3.0, -52.688], [18.2314, 3.0, -52.6039], [18.4582, 3.0, -52.5083], [18.6799, 3.0, -52.4015], [18.896, 3.0, -52.2838], [19.106, 3.0, -52.1555], [26.7105, 3.0, -55.2632], [21.3638, 3.0, -48.0095], [21.3577, 3.0, -47.7635], [21.3393, 3.0, -47.5181], [21.3087, 3.0, -47.2739], [21.2659, 3.0, -47.0316], [21.2112, 3.0, -46.7916], [21.1445, 3.0, -46.5547], [19.3094, 3.0, -52.0169], [21.0662, 3.0, -46.3215], [19.5055, 3.0, -51.8683], [19.694, 3.0, -51.7101], [19.8744, 3.0, -51.5427], [20.0463, 3.0, -51.3665], [20.2091, 3.0, -51.182], [20.3625, 3.0, -50.9896], [20.5062, 3.0, -50.7898], [20.6397, 3.0, -50.5831], [20.7628, 3.0, -50.37], [20.875, 3.0, -50.151], [20.9762, 3.0, -49.9266], [21.0662, 3.0, -49.6976], [21.1445, 3.0, -49.4643], [21.2112, 3.0, -49.2274], [21.2659, 3.0, -48.9875], [21.3087, 3.0, -48.7451], [21.3393, 3.0, -48.5009], [21.3577, 3.0, -48.2555], [26.7105, 3.0, -66.6904], [32.4211, 3.0, -60.7895], [-0.0, 17.2725, -18.399], [-0.0, 10.6576, -46.7187]], "f": [[0, 1, 2], [2, 1, 3], [4, 5, 6], [6, 5, 7], [8, 9, 10], [11, 12, 13], [13, 12, 5], [8, 14, 9], [1, 14, 8], [12, 15, 5], [14, 16, 17], [18, 19, 15], [19, 20, 15], [5, 20, 7], [15, 20, 5], [16, 21, 22], [14, 21, 16], [1, 21, 14], [23, 24, 25], [25, 24, 20], [21, 26, 27], [27, 26, 28], [1, 26, 21], [0, 26, 1], [0, 29, 26], [0, 30, 29], [31, 32, 33], [33, 32, 34], [34, 32, 35], [36, 37, 32], [24, 38, 20], [32, 38, 35], [37, 38, 32], [35, 38, 24], [20, 39, 7], [38, 39, 20], [7, 39, 0], [0, 40, 30], [39, 40, 0], [30, 40, 41], [39, 42, 43], [43, 44, 39], [39, 45, 42], [44, 46, 39], [39, 47, 45], [46, 48, 39], [39, 49, 47], [39, 50, 40], [48, 50, 39], [39, 51, 49], [50, 52, 40], [39, 53, 51], [52, 54, 40], [39, 55, 53], [54, 56, 40], [39, 57, 55], [56, 58, 40], [39, 59, 57], [58, 60, 40], [60, 61, 40], [61, 62, 40], [41, 63, 30], [62, 64, 40], [64, 65, 40], [65, 66, 40], [66, 67, 40], [67, 68, 40], [68, 69, 40], [69, 70, 40], [70, 71, 40], [71, 72, 40], [40, 72, 73], [72, 74, 73], [74, 75, 73], [76, 77, 78], [79, 77, 76], [80, 77, 79], [81, 77, 80], [82, 77, 81], [83, 77, 82], [84, 77, 83], [85, 77, 84], [86, 77, 85], [87, 77, 86], [88, 77, 87], [89, 77, 88], [59, 77, 89], [39, 77, 59], [77, 90, 78], [75, 91, 73], [77, 92, 90], [91, 93, 73], [77, 94, 92], [93, 95, 73], [77, 96, 94], [95, 97, 73], [77, 98, 96], [97, 99, 73], [77, 100, 98], [99, 101, 73], [77, 102, 100], [101, 103, 73], [77, 104, 102], [103, 105, 73], [77, 106, 104], [77, 107, 106], [77, 108, 107], [77, 109, 108], [77, 110, 109], [77, 111, 110], [63, 112, 30], [73, 113, 114], [115, 116, 117], [116, 118, 117], [119, 120, 121], [121, 120, 118], [122, 123, 120], [118, 123, 117], [120, 123, 118], [123, 124, 117], [125, 126, 124], [124, 126, 117], [127, 128, 126], [128, 129, 126], [129, 130, 126], [131, 130, 129], [130, 132, 126], [133, 134, 135], [135, 134, 132], [132, 136, 126], [134, 136, 132], [137, 138, 136], [138, 139, 136], [139, 140, 136], [140, 141, 136], [142, 143, 141], [141, 143, 136], [143, 144, 136], [136, 145, 126], [144, 145, 136], [146, 147, 145], [145, 147, 126], [117, 147, 148], [148, 147, 149], [149, 147, 150], [150, 147, 151], [151, 147, 152], [152, 147, 153], [153, 147, 154], [154, 147, 155], [155, 147, 156], [156, 147, 157], [157, 147, 158], [158, 147, 159], [159, 147, 160], [160, 147, 161], [161, 147, 162], [162, 147, 163], [163, 147, 164], [164, 147, 165], [165, 147, 166], [166, 147, 167], [167, 147, 168], [168, 147, 169], [169, 147, 170], [170, 147, 171], [171, 147, 172], [172, 147, 173], [173, 147, 174], [174, 147, 175], [126, 147, 117], [176, 177, 178], [179, 177, 176], [180, 177, 179], [181, 177, 180], [182, 177, 181], [183, 177, 182], [184, 177, 183], [185, 177, 184], [186, 177, 185], [187, 177, 186], [188, 177, 187], [189, 177, 188], [190, 177, 189], [191, 177, 190], [192, 177, 191], [193, 177, 192], [194, 177, 193], [195, 177, 194], [77, 177, 111], [196, 177, 195], [197, 177, 196], [198, 177, 197], [199, 177, 198], [200, 177, 199], [111, 177, 200], [175, 177, 201], [201, 177, 202], [202, 177, 203], [203, 177, 204], [204, 177, 205], [205, 177, 77], [147, 177, 175], [113, 206, 63], [63, 206, 112], [207, 208, 105], [209, 210, 207], [211, 210, 209], [207, 210, 208], [105, 212, 73], [208, 212, 105], [211, 213, 210], [212, 214, 73], [215, 216, 211], [211, 216, 213], [73, 217, 113], [214, 217, 73], [218, 219, 215], [220, 219, 218], [215, 219, 216], [217, 221, 113], [222, 223, 220], [220, 223, 219], [221, 224, 113], [222, 225, 223], [224, 226, 113], [227, 228, 222], [222, 228, 225], [226, 229, 113], [230, 231, 227], [227, 231, 228], [229, 232, 113], [230, 233, 231], [234, 233, 230], [235, 233, 234], [232, 236, 113], [235, 237, 233], [236, 238, 113], [239, 240, 235], [235, 240, 237], [238, 241, 113], [242, 243, 239], [239, 243, 240], [241, 244, 113], [245, 246, 242], [242, 246, 243], [244, 247, 113], [248, 249, 245], [245, 249, 246], [247, 250, 113], [248, 251, 249], [252, 251, 248], [250, 253, 113], [252, 254, 251], [255, 254, 252], [253, 256, 113], [257, 258, 255], [259, 258, 257], [255, 258, 254], [256, 260, 113], [259, 261, 258], [262, 261, 259], [260, 263, 113], [262, 264, 261], [263, 265, 113], [262, 266, 264], [267, 266, 262], [265, 268, 113], [267, 269, 266], [270, 269, 267], [268, 271, 113], [272, 273, 270], [274, 273, 272], [270, 273, 269], [271, 275, 113], [274, 276, 273], [275, 277, 113], [278, 279, 274], [274, 279, 276], [277, 280, 113], [281, 282, 278], [278, 282, 279], [280, 283, 113], [284, 285, 281], [281, 285, 282], [283, 286, 113], [287, 288, 284], [289, 288, 287], [284, 288, 285], [286, 290, 113], [289, 291, 288], [290, 292, 113], [293, 294, 289], [289, 294, 291], [292, 295, 113], [296, 297, 293], [298, 297, 296], [293, 297, 294], [295, 299, 113], [298, 300, 297], [301, 300, 298], [299, 302, 113], [303, 304, 301], [301, 304, 300], [302, 305, 113], [303, 306, 304], [305, 307, 113], [303, 308, 306], [309, 308, 303], [178, 308, 309], [113, 310, 206], [307, 310, 113], [178, 311, 308], [310, 312, 206], [312, 313, 206], [313, 314, 206], [314, 315, 206], [315, 316, 206], [177, 317, 178], [318, 317, 319], [320, 317, 318], [321, 317, 320], [322, 317, 321], [323, 317, 322], [324, 317, 323], [325, 317, 324], [326, 317, 325], [327, 317, 326], [178, 317, 311], [328, 317, 327], [329, 317, 328], [330, 317, 329], [331, 317, 330], [332, 317, 331], [333, 317, 332], [334, 317, 333], [335, 317, 334], [336, 317, 335], [337, 317, 336], [338, 317, 337], [339, 317, 338], [340, 317, 339], [341, 317, 340], [311, 317, 341], [316, 342, 206], [343, 342, 344], [345, 342, 343], [346, 342, 345], [347, 342, 346], [348, 342, 347], [349, 342, 348], [350, 342, 349], [351, 342, 350], [352, 342, 351], [353, 342, 352], [354, 342, 353], [355, 342, 354], [356, 342, 355], [357, 342, 356], [317, 342, 319], [358, 342, 357], [359, 342, 358], [360, 342, 359], [361, 342, 316], [362, 342, 360], [363, 342, 361], [364, 342, 362], [365, 342, 363], [319, 342, 364], [366, 342, 365], [367, 342, 366], [368, 342, 367], [369, 342, 368], [344, 342, 369], [342, 370, 371], [317, 370, 342], [372, 373, 374], [372, 374, 375], [376, 377, 378], [376, 379, 377], [380, 381, 382], [380, 382, 383], [380, 383, 372], [384, 385, 386], [387, 380, 372], [387, 388, 389], [387, 389, 380], [387, 372, 375], [390, 379, 376], [390, 376, 385], [390, 384, 391], [390, 385, 384], [390, 392, 393], [390, 393, 379], [394, 395, 396], [394, 396, 387], [397, 390, 398], [397, 398, 399], [397, 392, 390], [397, 400, 392], [401, 387, 375], [401, 394, 387], [402, 400, 397], [403, 400, 402], [404, 405, 406], [404, 406, 407], [404, 407, 401], [408, 401, 375], [408, 404, 401], [408, 409, 410], [408, 410, 404], [411, 408, 375], [411, 375, 400], [412, 411, 400], [412, 400, 403], [412, 403, 413], [414, 415, 416], [417, 411, 418], [419, 418, 411], [420, 411, 417], [421, 419, 411], [422, 411, 420], [423, 421, 411], [424, 411, 422], [425, 411, 412], [425, 423, 411], [426, 411, 424], [427, 425, 412], [428, 411, 426], [429, 427, 412], [430, 411, 428], [431, 429, 412], [432, 411, 430], [433, 431, 412], [434, 411, 432], [435, 433, 412], [436, 435, 412], [437, 414, 416], [438, 436, 412], [439, 413, 403], [440, 438, 412], [441, 440, 412], [442, 441, 412], [443, 442, 412], [443, 412, 415], [444, 443, 415], [445, 444, 415], [446, 445, 415], [447, 446, 415], [448, 447, 415], [449, 448, 415], [450, 449, 415], [451, 411, 434], [451, 452, 453], [451, 454, 452], [451, 455, 454], [451, 456, 455], [451, 457, 456], [451, 458, 457], [451, 459, 458], [451, 460, 459], [451, 461, 460], [451, 462, 461], [451, 463, 462], [451, 464, 463], [451, 434, 464], [465, 451, 453], [466, 450, 415], [467, 451, 465], [468, 466, 415], [469, 451, 467], [470, 468, 415], [471, 451, 469], [472, 470, 415], [473, 451, 471], [474, 472, 415], [475, 451, 473], [476, 474, 415], [477, 451, 475], [478, 476, 415], [479, 451, 477], [480, 478, 415], [481, 451, 479], [482, 480, 415], [483, 451, 481], [484, 451, 483], [485, 451, 484], [486, 451, 485], [487, 451, 486], [488, 439, 403], [489, 414, 437], [490, 491, 492], [493, 490, 492], [494, 495, 496], [494, 496, 493], [497, 493, 492], [497, 498, 494], [497, 494, 493], [499, 497, 492], [500, 501, 499], [500, 499, 492], [502, 503, 500], [504, 502, 500], [505, 506, 504], [505, 504, 500], [507, 508, 505], [509, 510, 511], [509, 511, 512], [509, 512, 507], [513, 514, 509], [515, 507, 505], [515, 509, 507], [515, 513, 509], [516, 517, 515], [516, 515, 505], [518, 519, 516], [518, 516, 505], [520, 505, 500], [520, 518, 505], [521, 522, 520], [521, 500, 492], [521, 492, 523], [521, 520, 500], [521, 523, 524], [521, 524, 525], [521, 525, 526], [521, 526, 527], [521, 527, 528], [521, 528, 529], [521, 529, 530], [521, 530, 531], [521, 531, 532], [521, 532, 533], [521, 533, 534], [521, 534, 535], [521, 535, 536], [521, 536, 537], [521, 537, 538], [521, 538, 539], [521, 539, 540], [521, 540, 541], [521, 541, 542], [521, 542, 543], [521, 543, 544], [521, 544, 545], [521, 545, 546], [521, 546, 547], [521, 547, 548], [521, 548, 549], [521, 549, 550], [551, 552, 553], [551, 554, 552], [551, 555, 554], [551, 556, 555], [551, 557, 556], [551, 558, 557], [551, 559, 558], [551, 560, 559], [551, 561, 560], [551, 562, 561], [551, 563, 562], [551, 564, 563], [551, 451, 487], [551, 565, 564], [551, 566, 565], [551, 567, 566], [551, 568, 567], [551, 569, 568], [551, 570, 569], [551, 571, 570], [551, 572, 571], [551, 573, 572], [551, 574, 573], [551, 487, 574], [551, 550, 575], [551, 575, 576], [551, 576, 577], [551, 577, 578], [551, 578, 579], [551, 579, 451], [551, 521, 550], [580, 482, 415], [580, 581, 582], [580, 583, 581], [580, 584, 583], [580, 585, 584], [580, 586, 585], [580, 587, 586], [580, 588, 587], [580, 589, 588], [580, 590, 589], [580, 591, 482], [580, 592, 590], [580, 593, 591], [580, 594, 592], [580, 595, 593], [580, 596, 594], [580, 597, 595], [580, 598, 596], [580, 599, 597], [580, 600, 598], [580, 601, 599], [580, 602, 600], [580, 603, 601], [580, 604, 602], [580, 605, 603], [580, 606, 604], [580, 607, 605], [580, 608, 606], [580, 609, 607], [580, 610, 608], [580, 611, 609], [580, 553, 610], [580, 612, 611], [580, 613, 612], [580, 614, 613], [580, 615, 614], [580, 582, 615], [580, 551, 553], [616, 439, 488], [616, 489, 439], [617, 551, 580], [618, 617, 414], [619, 617, 618], [620, 618, 414], [621, 617, 619], [622, 620, 414], [623, 617, 621], [624, 622, 414], [625, 617, 623], [626, 624, 414], [627, 617, 625], [628, 626, 414], [629, 617, 627], [630, 414, 489], [630, 628, 414], [631, 617, 629], [632, 630, 489], [633, 617, 631], [634, 632, 489], [635, 617, 633], [636, 634, 489], [637, 617, 635], [638, 636, 489], [639, 617, 637], [640, 638, 489], [641, 617, 639], [642, 640, 489], [643, 617, 641], [644, 642, 489], [645, 617, 643], [646, 644, 489], [647, 617, 645], [648, 646, 489], [649, 617, 647], [650, 648, 489], [651, 617, 649], [652, 650, 489], [653, 617, 651], [654, 652, 489], [655, 617, 653], [656, 654, 489], [657, 617, 655], [658, 656, 489], [659, 617, 657], [660, 658, 489], [661, 617, 659], [662, 660, 489], [663, 617, 661], [664, 662, 489], [665, 617, 663], [666, 664, 489], [667, 617, 665], [668, 666, 489], [669, 617, 667], [670, 668, 489], [671, 617, 669], [672, 670, 489], [673, 617, 671], [674, 672, 489], [675, 617, 673], [676, 674, 489], [677, 617, 675], [678, 676, 489], [679, 617, 677], [680, 678, 489], [681, 617, 679], [682, 680, 489], [683, 617, 681], [684, 682, 489], [685, 617, 683], [686, 489, 616], [686, 684, 489], [687, 617, 685], [688, 686, 616], [689, 617, 687], [690, 688, 616], [691, 690, 616], [692, 691, 616], [693, 692, 616], [694, 617, 689], [694, 689, 695], [694, 695, 696], [694, 696, 697], [694, 697, 698], [694, 698, 699], [694, 699, 700], [694, 700, 701], [694, 701, 702], [694, 702, 703], [694, 703, 704], [694, 704, 705], [694, 705, 706], [694, 706, 707], [694, 707, 708], [694, 708, 709], [694, 709, 710], [694, 710, 711], [694, 711, 712], [694, 712, 713], [694, 713, 714], [694, 714, 715], [694, 715, 716], [694, 716, 717], [694, 551, 617], [718, 693, 616], [718, 694, 717], [718, 719, 720], [718, 720, 721], [718, 721, 722], [718, 722, 723], [718, 723, 724], [718, 724, 725], [718, 717, 726], [718, 725, 727], [718, 726, 728], [718, 727, 693], [718, 728, 729], [718, 729, 730], [718, 730, 731], [718, 731, 732], [718, 732, 733], [718, 733, 734], [718, 734, 735], [718, 735, 736], [718, 736, 737], [718, 737, 738], [718, 738, 739], [718, 739, 740], [718, 740, 741], [718, 741, 742], [718, 742, 743], [718, 743, 744], [718, 744, 745], [718, 745, 719], [746, 718, 747], [746, 694, 718], [412, 416, 415], [718, 616, 342], [342, 616, 206], [747, 718, 371], [371, 718, 342], [746, 747, 370], [370, 747, 371], [694, 746, 317], [317, 746, 370], [694, 317, 551], [551, 317, 177], [147, 551, 177], [521, 551, 147], [115, 117, 492], [115, 492, 491], [116, 491, 490], [116, 115, 491], [118, 490, 493], [118, 116, 490], [121, 493, 496], [121, 118, 493], [119, 496, 495], [119, 121, 496], [120, 495, 494], [120, 119, 495], [122, 494, 498], [122, 120, 494], [123, 122, 498], [123, 498, 497], [124, 123, 497], [124, 499, 501], [124, 497, 499], [125, 124, 501], [126, 125, 501], [126, 501, 500], [127, 126, 500], [127, 503, 502], [127, 500, 503], [128, 127, 502], [129, 128, 502], [129, 502, 504], [131, 129, 504], [131, 504, 506], [130, 131, 506], [130, 506, 505], [132, 130, 505], [132, 505, 508], [135, 132, 508], [135, 507, 512], [135, 508, 507], [133, 512, 511], [133, 135, 512], [134, 133, 511], [136, 510, 509], [136, 511, 510], [136, 134, 511], [137, 509, 514], [137, 136, 509], [138, 137, 514], [139, 514, 513], [139, 138, 514], [140, 513, 515], [140, 139, 513], [141, 515, 517], [141, 140, 515], [142, 516, 519], [142, 517, 516], [142, 141, 517], [143, 142, 519], [144, 519, 518], [144, 143, 519], [145, 518, 520], [145, 144, 518], [146, 520, 522], [146, 145, 520], [147, 522, 521], [147, 146, 522], [492, 117, 148], [523, 492, 148], [204, 205, 579], [204, 579, 578], [203, 578, 577], [203, 204, 578], [202, 577, 576], [202, 203, 577], [201, 576, 575], [201, 202, 576], [175, 575, 550], [175, 201, 575], [174, 550, 549], [174, 175, 550], [173, 549, 548], [173, 174, 549], [172, 173, 548], [172, 548, 547], [171, 172, 547], [171, 547, 546], [170, 171, 546], [170, 546, 545], [169, 170, 545], [169, 545, 544], [168, 169, 544], [168, 544, 543], [167, 168, 543], [167, 542, 541], [167, 543, 542], [166, 167, 541], [165, 166, 541], [165, 541, 540], [164, 165, 540], [164, 540, 539], [163, 164, 539], [163, 539, 538], [162, 163, 538], [162, 538, 537], [161, 537, 536], [161, 162, 537], [160, 536, 535], [160, 161, 536], [159, 160, 535], [159, 535, 534], [158, 533, 532], [158, 534, 533], [158, 159, 534], [157, 158, 532], [156, 532, 531], [156, 157, 532], [155, 531, 530], [155, 156, 531], [154, 529, 528], [154, 530, 529], [154, 155, 530], [153, 154, 528], [152, 528, 527], [152, 153, 528], [151, 527, 526], [151, 152, 527], [150, 526, 525], [150, 151, 526], [149, 525, 524], [149, 150, 525], [148, 524, 523], [148, 149, 524], [451, 205, 77], [451, 579, 205], [411, 77, 39], [411, 451, 77], [6, 7, 375], [6, 375, 374], [4, 374, 373], [4, 6, 374], [5, 372, 383], [5, 373, 372], [5, 4, 373], [13, 5, 383], [11, 383, 382], [11, 13, 383], [12, 382, 381], [12, 11, 382], [15, 381, 380], [15, 12, 381], [18, 389, 388], [18, 380, 389], [18, 15, 380], [19, 18, 388], [20, 388, 387], [20, 19, 388], [25, 387, 396], [25, 20, 387], [23, 396, 395], [23, 25, 396], [24, 23, 395], [24, 394, 401], [24, 395, 394], [35, 24, 401], [34, 35, 401], [34, 401, 407], [33, 34, 407], [33, 407, 406], [31, 33, 406], [31, 405, 404], [31, 406, 405], [32, 31, 404], [36, 404, 410], [36, 32, 404], [37, 36, 410], [37, 410, 409], [38, 409, 408], [38, 37, 409], [39, 408, 411], [39, 38, 408], [400, 7, 0], [400, 375, 7], [29, 30, 403], [29, 403, 402], [26, 402, 397], [26, 29, 402], [28, 397, 399], [28, 26, 397], [27, 398, 390], [27, 399, 398], [27, 28, 399], [21, 27, 390], [22, 390, 391], [22, 21, 390], [16, 391, 384], [16, 22, 391], [17, 384, 386], [17, 16, 384], [14, 386, 385], [14, 17, 386], [9, 385, 376], [9, 14, 385], [10, 376, 378], [10, 9, 376], [8, 377, 379], [8, 378, 377], [8, 10, 378], [1, 8, 379], [3, 379, 393], [3, 1, 379], [2, 393, 392], [2, 3, 393], [0, 392, 400], [0, 2, 392], [112, 488, 403], [112, 403, 30], [616, 112, 206], [616, 488, 112], [748, 415, 414], [414, 617, 749], [748, 414, 749], [749, 617, 580], [749, 415, 748], [749, 580, 415], [582, 581, 255], [255, 581, 257], [257, 583, 259], [259, 583, 262], [581, 583, 257], [583, 584, 262], [262, 585, 267], [267, 585, 270], [584, 585, 262], [270, 586, 272], [585, 586, 270], [586, 587, 272], [272, 588, 274], [587, 588, 272], [274, 589, 278], [278, 589, 281], [588, 589, 274], [589, 590, 281], [281, 592, 284], [590, 592, 281], [592, 594, 284], [284, 594, 287], [594, 596, 287], [287, 596, 289], [596, 598, 289], [289, 598, 293], [598, 600, 293], [293, 600, 296], [600, 602, 296], [296, 602, 298], [602, 604, 298], [298, 604, 301], [604, 606, 301], [301, 606, 303], [606, 608, 303], [303, 608, 309], [608, 610, 309], [309, 610, 178], [610, 553, 178], [178, 553, 176], [176, 553, 179], [553, 552, 179], [552, 554, 179], [179, 554, 180], [180, 554, 181], [554, 555, 181], [181, 556, 182], [182, 556, 183], [555, 556, 181], [556, 557, 183], [183, 558, 184], [557, 558, 183], [184, 559, 185], [185, 559, 186], [558, 559, 184], [186, 560, 187], [559, 560, 186], [560, 561, 187], [187, 562, 188], [188, 562, 189], [561, 562, 187], [562, 563, 189], [189, 564, 190], [190, 564, 191], [563, 564, 189], [564, 565, 191], [191, 566, 192], [192, 566, 193], [565, 566, 191], [566, 567, 193], [567, 568, 193], [193, 568, 194], [568, 569, 194], [194, 569, 195], [569, 570, 195], [195, 570, 196], [570, 571, 196], [196, 571, 197], [571, 572, 197], [197, 572, 198], [198, 572, 199], [572, 573, 199], [573, 574, 199], [199, 574, 200], [574, 487, 200], [200, 487, 111], [487, 486, 111], [111, 486, 110], [486, 485, 110], [110, 485, 109], [485, 484, 109], [109, 484, 108], [484, 483, 108], [108, 483, 107], [483, 481, 107], [107, 481, 106], [481, 479, 106], [106, 479, 104], [479, 477, 104], [104, 477, 102], [477, 475, 102], [102, 475, 100], [475, 473, 100], [100, 473, 98], [473, 471, 98], [98, 471, 96], [471, 469, 96], [96, 469, 94], [469, 467, 94], [94, 467, 92], [467, 465, 92], [92, 465, 90], [465, 453, 90], [90, 453, 78], [78, 452, 76], [453, 452, 78], [76, 454, 79], [452, 454, 76], [79, 455, 80], [454, 455, 79], [80, 456, 81], [455, 456, 80], [456, 457, 81], [81, 457, 82], [457, 458, 82], [82, 458, 83], [458, 459, 83], [83, 459, 84], [459, 460, 84], [84, 460, 85], [460, 461, 85], [85, 461, 86], [461, 462, 86], [86, 462, 87], [462, 463, 87], [87, 463, 88], [463, 464, 88], [88, 464, 89], [464, 434, 89], [89, 434, 59], [434, 432, 59], [59, 432, 57], [432, 430, 57], [57, 430, 55], [430, 428, 55], [55, 428, 53], [428, 426, 53], [53, 426, 51], [51, 424, 49], [426, 424, 51], [49, 422, 47], [424, 422, 49], [47, 420, 45], [422, 420, 47], [45, 417, 42], [420, 417, 45], [42, 418, 43], [417, 418, 42], [43, 419, 44], [418, 419, 43], [44, 421, 46], [419, 421, 44], [46, 423, 48], [421, 423, 46], [48, 425, 50], [423, 425, 48], [50, 427, 52], [425, 427, 50], [52, 429, 54], [427, 429, 52], [54, 431, 56], [429, 431, 54], [56, 433, 58], [431, 433, 56], [433, 435, 58], [58, 435, 60], [435, 436, 60], [60, 436, 61], [436, 438, 61], [61, 438, 62], [438, 440, 62], [62, 440, 64], [64, 441, 65], [440, 441, 64], [65, 442, 66], [66, 442, 67], [441, 442, 65], [442, 443, 67], [67, 444, 68], [443, 444, 67], [68, 445, 69], [444, 445, 68], [69, 446, 70], [445, 446, 69], [70, 447, 71], [446, 447, 70], [71, 448, 72], [72, 448, 74], [447, 448, 71], [448, 449, 74], [74, 450, 75], [449, 450, 74], [75, 466, 91], [450, 466, 75], [91, 468, 93], [93, 468, 95], [466, 468, 91], [468, 470, 95], [95, 472, 97], [470, 472, 95], [97, 474, 99], [472, 474, 97], [99, 476, 101], [101, 476, 103], [474, 476, 99], [476, 478, 103], [103, 480, 105], [105, 480, 207], [478, 480, 103], [480, 482, 207], [207, 591, 209], [482, 591, 207], [591, 593, 209], [209, 593, 211], [593, 595, 211], [211, 595, 215], [595, 597, 215], [215, 597, 218], [597, 599, 218], [218, 599, 220], [599, 601, 220], [220, 601, 222], [601, 603, 222], [222, 603, 227], [603, 605, 227], [227, 605, 230], [605, 607, 230], [230, 607, 234], [607, 609, 234], [234, 609, 235], [609, 611, 235], [235, 611, 239], [611, 612, 239], [239, 612, 242], [612, 613, 242], [242, 613, 245], [245, 614, 248], [613, 614, 245], [614, 615, 248], [248, 615, 252], [252, 582, 255], [615, 582, 252], [719, 745, 344], [344, 745, 343], [343, 744, 345], [745, 744, 343], [345, 743, 346], [744, 743, 345], [346, 742, 347], [743, 742, 346], [347, 741, 348], [742, 741, 347], [348, 740, 349], [741, 740, 348], [349, 739, 350], [740, 739, 349], [350, 738, 351], [739, 738, 350], [351, 737, 352], [738, 737, 351], [352, 736, 353], [737, 736, 352], [736, 735, 353], [353, 735, 354], [735, 734, 354], [354, 734, 355], [734, 733, 355], [355, 733, 356], [733, 732, 356], [356, 732, 357], [732, 731, 357], [357, 731, 358], [731, 730, 358], [358, 730, 359], [730, 729, 359], [359, 729, 360], [729, 728, 360], [360, 728, 362], [728, 726, 362], [362, 726, 364], [726, 717, 364], [364, 717, 319], [717, 716, 319], [319, 716, 318], [716, 715, 318], [318, 715, 320], [320, 714, 321], [715, 714, 320], [321, 713, 322], [714, 713, 321], [322, 712, 323], [713, 712, 322], [323, 711, 324], [712, 711, 323], [324, 710, 325], [711, 710, 324], [325, 709, 326], [710, 709, 325], [326, 708, 327], [709, 708, 326], [327, 707, 328], [708, 707, 327], [328, 706, 329], [707, 706, 328], [329, 705, 330], [706, 705, 329], [330, 704, 331], [705, 704, 330], [331, 703, 332], [704, 703, 331], [332, 702, 333], [703, 702, 332], [333, 701, 334], [702, 701, 333], [701, 700, 334], [334, 700, 335], [700, 699, 335], [335, 699, 336], [699, 698, 336], [336, 698, 337], [698, 697, 337], [337, 697, 338], [697, 696, 338], [338, 696, 339], [696, 695, 339], [339, 695, 340], [695, 689, 340], [340, 689, 341], [689, 687, 341], [341, 687, 311], [687, 685, 311], [311, 685, 308], [685, 683, 308], [308, 683, 306], [683, 681, 306], [306, 681, 304], [681, 679, 304], [304, 679, 300], [679, 677, 300], [300, 677, 297], [677, 675, 297], [297, 675, 294], [675, 673, 294], [294, 673, 291], [673, 671, 291], [291, 671, 288], [671, 669, 288], [288, 669, 285], [669, 667, 285], [285, 667, 282], [667, 665, 282], [282, 665, 279], [665, 663, 279], [279, 663, 276], [663, 661, 276], [276, 661, 273], [273, 659, 269], [661, 659, 273], [269, 657, 266], [659, 657, 269], [266, 655, 264], [657, 655, 266], [264, 653, 261], [655, 653, 264], [653, 651, 261], [261, 651, 258], [651, 649, 258], [258, 649, 254], [649, 647, 254], [254, 647, 251], [647, 645, 251], [251, 645, 249], [645, 643, 249], [249, 643, 246], [643, 641, 246], [246, 641, 243], [641, 639, 243], [243, 639, 240], [639, 637, 240], [240, 637, 237], [637, 635, 237], [237, 635, 233], [635, 633, 233], [233, 633, 231], [633, 631, 231], [231, 631, 228], [631, 629, 228], [228, 629, 225], [223, 627, 219], [629, 627, 225], [225, 627, 223], [627, 625, 219], [219, 623, 216], [625, 623, 219], [216, 621, 213], [623, 621, 216], [213, 619, 210], [210, 619, 208], [621, 619, 213], [619, 618, 208], [208, 620, 212], [618, 620, 208], [212, 622, 214], [214, 622, 217], [620, 622, 212], [622, 624, 217], [217, 626, 221], [624, 626, 217], [221, 628, 224], [626, 628, 221], [224, 630, 226], [628, 630, 224], [226, 632, 229], [229, 632, 232], [630, 632, 226], [632, 634, 232], [634, 636, 232], [232, 636, 236], [236, 636, 238], [636, 638, 238], [238, 638, 241], [638, 640, 241], [241, 642, 244], [640, 642, 241], [244, 644, 247], [642, 644, 244], [247, 646, 250], [644, 646, 247], [250, 648, 253], [646, 648, 250], [253, 650, 256], [648, 650, 253], [256, 652, 260], [260, 652, 263], [650, 652, 256], [652, 654, 263], [263, 656, 265], [654, 656, 263], [265, 658, 268], [268, 658, 271], [656, 658, 265], [658, 660, 271], [271, 662, 275], [660, 662, 271], [275, 664, 277], [662, 664, 275], [277, 666, 280], [664, 666, 277], [280, 668, 283], [666, 668, 280], [283, 670, 286], [668, 670, 283], [286, 672, 290], [670, 672, 286], [290, 674, 292], [672, 674, 290], [292, 676, 295], [674, 676, 292], [295, 678, 299], [299, 678, 302], [676, 678, 295], [678, 680, 302], [302, 682, 305], [305, 682, 307], [680, 682, 302], [682, 684, 307], [684, 686, 307], [307, 686, 310], [686, 688, 310], [310, 688, 312], [688, 690, 312], [312, 690, 313], [690, 691, 313], [313, 691, 314], [691, 692, 314], [314, 692, 315], [315, 692, 316], [692, 693, 316], [693, 727, 316], [316, 727, 361], [727, 725, 361], [361, 725, 363], [725, 724, 363], [363, 724, 365], [724, 723, 365], [365, 723, 366], [723, 722, 366], [366, 722, 367], [722, 721, 367], [367, 721, 368], [368, 720, 369], [721, 720, 368], [369, 719, 344], [720, 719, 369], [437, 73, 114], [437, 416, 73], [40, 73, 412], [73, 416, 412], [40, 412, 41], [41, 412, 413], [439, 63, 413], [413, 63, 41], [63, 489, 113], [439, 489, 63], [113, 437, 114], [489, 437, 113]]} \ No newline at end of file diff --git a/docs/CAD/design/mate-connectors/circularmateconnectors.png b/docs/CAD/design/mate-connectors/circularmateconnectors.png deleted file mode 100644 index 3150a5667b..0000000000 Binary files a/docs/CAD/design/mate-connectors/circularmateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/cmp-sheet.png b/docs/CAD/design/mate-connectors/cmp-sheet.png deleted file mode 100644 index 1d67ae31ed..0000000000 Binary files a/docs/CAD/design/mate-connectors/cmp-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/connector-glyph-proposal.html b/docs/CAD/design/mate-connectors/connector-glyph-proposal.html deleted file mode 100644 index 2a8475ee24..0000000000 --- a/docs/CAD/design/mate-connectors/connector-glyph-proposal.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - -Mate connector glyph — polarity and verse - - - -
- -
-
Orca Design · assembly
-

Mate connector glyph — polarity and verse

-

- Onshape's core (disc + roll quadrant + Z arrow) is adopted unchanged because it is proven and - aligned. The addition is polarity — which connector is anchored and - which one travels — which no surveyed CAD system encodes in its glyph. -

-
- -

The three jobs of the glyph

-
-
-
- - - - -
-
Disc — the XY plane
-

Says “I am a frame, and this is the plane I sit in.” The dot is the exact origin.

-
- -
-
- - - - - -
-
Quadrant — the roll
-

- The filled sector is the +X/+Y quadrant. It steps 90° with the reorient control, so the - clocking that Fastened and Slider lock is visible before you commit. -

-
- -
-
- - - - - - - -
-
Arrow — the verse
-

- Drawn on +Z only. Nothing below the disc. A double-headed axis is what - makes people ask which way it points; a one-sided arrow cannot be misread. -

-
-
- -

Polarity — the part nobody else draws

-
-
-
- - - - - - - - -
-
Fixed — the socket
-

- Hollow head, muted colour. This body does not move. It receives. -

-
- -
-
- - - - - - - -
-
Driven — the plug
-

- Solid head, active colour. This body is the one that jumps. It inserts. -

-
- -
-
- - - - - - - - - - - - -
-
Roll undefined
-

- Hatched quadrant, dashed disc: a circular face or a seam gave no usable direction. Says - “pick a direction” without a dialog. -

-
-
- -

The pair reads as a magnet

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - fixed · receives - driven · inserts - -
-

- Two arrows nose to nose. Because a magnet's north seeks a south, “facing” is the - self-evident default — which settles open decision D1 on visual grounds instead of a - convention nobody can look up. Nothing has to be remembered: the picture is the rule. - The dashed line is what makes the two glyphs read as one object. -

-
- -

States

-
- - - - - - - - - - - - - - - - - - - - - -
StateDrawingWhy
Candidate (hover)small dot onlyOnshape draws plain white dots at every corner and midpoint. Dots propose; the full glyph commits.
Pickeddisc + quadrant + coneThe committed frame, with roll and verse both readable.
Roll undefinedhatched quadrant, dashed discTurns requirement R8 from a message nobody reads into a mark you cannot miss.
-
- -

Constraints on the drawing

-
-

- Do not make it a fourth RGB triad. The bed-centre world triad - (DesignCanvas.cpp:65) and the move gizmo are already three coloured arrows. The disc - and the quadrant are what tell a connector apart from those — keep the arms short, and consider - drawing only Z on the committed glyph, with X and Y implied by the quadrant. -

-
- roll quadrant - Z / driven - fixed - roll undefined -
-
- -
- - diff --git a/docs/CAD/design/mate-connectors/coplanar_test.py b/docs/CAD/design/mate-connectors/coplanar_test.py deleted file mode 100644 index ea02ed3c80..0000000000 --- a/docs/CAD/design/mate-connectors/coplanar_test.py +++ /dev/null @@ -1,68 +0,0 @@ -# Does the connector pair let two hosts sit COPLANAR, or does it hold them apart? -# -# The male's flat back is the plane Y=0 and all its relief rises to +Y. So Y=0 is the natural -# mating datum: everything the male adds lives on one side of it. The test below builds two dummy -# host plates that meet on that plane -- one with the male FUSED on, one with the cavity CUT in -- -# and measures whether they touch, interfere, or stand apart. -# -# It also emits the artifact that makes this work in practice: a CUTTER solid (the male grown by -# the clearance) that you subtract from any host. A standalone female block cannot keep two hosts -# coplanar, because its own floor material stands between them; a cavity can. -# -# Run: /snap/bin/freecad.cmd coplanar_test.py - -import os -import FreeCAD as App -import Part -from FreeCAD import Vector - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -CLEAR = 0.20 - -male = Part.Shape(); male.read(MALE); male = male.Solids[0] -bb = male.BoundBox -print(f"male relief: Y {bb.YMin:.3f} .. {bb.YMax:.3f} -> datum plane Y=0, all relief on +Y") - -# the flat back face, and proof it is the whole silhouette sitting on Y=0 -back = max((f for f in male.Faces - if abs(f.CenterOfMass.y) < 1e-6 and abs(abs(f.normalAt(0, 0).y) - 1) < 1e-6), - key=lambda f: f.Area) -print(f"back face : {back.Area:.1f} mm2 on Y=0 -- this is the contact surface") - -# ---- the cutter: the male grown by the clearance, poking 0.2 mm proud so the boolean is clean -cutter = male.makeOffsetShape(CLEAR, 1e-6, False, False, 0, 2, False).Solids[0] -cb = cutter.BoundBox -print(f"cutter : Y {cb.YMin:.3f} .. {cb.YMax:.3f}, {cutter.Volume/1000:.2f} cm3") - -# ---- two dummy hosts meeting on Y = 0 -W, H = 120.0, 100.0 -hostA = Part.makeBox(W, 10.0, H, Vector(-W/2, -10.0, -15.0)) # occupies Y -10..0 -hostB = Part.makeBox(W, 30.0, H, Vector(-W/2, 0.0, -15.0)) # occupies Y 0..30 - -partA = hostA.fuse(male) # male stands proud of A's face -partB = hostB.cut(cutter) # cavity sunk into B from its face - -print(f"\npart A (host + male) : {partA.Volume/1000:.2f} cm3") -print(f"part B (host - cutter) : {partB.Volume/1000:.2f} cm3") - -# ---- the question ------------------------------------------------------------------ -inter = partA.common(partB) -iv = inter.Volume if inter.Solids else 0.0 -gap = partA.distToShape(partB)[0] -print(f"\nRESULT interference A vs B : {iv:.6f} mm3 (0 = they do not collide)") -print(f"RESULT closest approach : {gap:.4f} mm (0 = the host faces are touching)") - -# are the two host faces actually on the same plane? -fa = [f for f in partA.Faces if abs(f.CenterOfMass.y) < 1e-9 and abs(abs(f.normalAt(0,0).y)-1) < 1e-6] -fb = [f for f in partB.Faces if abs(f.CenterOfMass.y) < 1e-9 and abs(abs(f.normalAt(0,0).y)-1) < 1e-6] -print(f"RESULT A has {len(fa)} face(s) lying exactly on Y=0, total {sum(f.Area for f in fa):.1f} mm2") -print(f"RESULT B has {len(fb)} face(s) lying exactly on Y=0, total {sum(f.Area for f in fb):.1f} mm2") -print("RESULT -> the hosts meet on Y=0: COPLANAR" if fa and fb and iv < 1e-3 - else "RESULT -> NOT coplanar") - -doc = App.newDocument("Cutter") -o = doc.addObject("Part::Feature", "BearConnector_Cutter"); o.Shape = cutter -doc.recompute() -Part.export([o], os.path.join(HERE, "BearConnector_Cutter.step")) -print(f"\nwrote BearConnector_Cutter.step -- subtract this from any host to get the socket") diff --git a/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png b/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png deleted file mode 100644 index e4c1cebcf9..0000000000 Binary files a/docs/CAD/design/mate-connectors/cylindricalmateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/faceted_ridge_key.scad b/docs/CAD/design/mate-connectors/faceted_ridge_key.scad deleted file mode 100644 index 3eb60064fb..0000000000 --- a/docs/CAD/design/mate-connectors/faceted_ridge_key.scad +++ /dev/null @@ -1,140 +0,0 @@ -// Faceted ridge key — asymmetric male/female alignment feature, flat facets only. -// -// 6 vertices, 7 faces, one closed manifold. Euler check: V - E + F = 6 - 11 + 7 = 2. -// No spheres, no cylinders, no splines, no fillets. -// -// THE FLANKS ARE TRIANGULATED EXPLICITLY, and that is not cosmetic. Written as quads -// [0,3,5,4] and [1,4,5,2] they are NOT planar — the base edge and the ridge edge are -// skew, so the four corners do not share a plane. A checker caught this after the first -// draft claimed the opposite. Left as quads, the tessellator picks the fold direction for -// you, which means the "flat facet" promise is broken by an unspecified crease and two -// exporters can disagree about the shape. Splitting them here fixes the crease at -// back-bottom -> front-ridge, which keeps the rear peak's triangle large and clean. -// -// FRAME CONVENTION (matches the CAD mate connector it is derived from): -// +Z the mating axis — the feature protrudes along it -// +X the roll reference — the ridge runs along it, low end forward -// +Y completes the right-handed frame -// -// WHAT BREAKS WHICH SYMMETRY -// rotational about Z ....... the ridge (elongation along X) -// 180 deg about Z .......... the ridge SLOPE: tall steep back, long shallow front -// mirror across XZ ......... deliberately NOT broken. Handedness is fixed by convention, -// so +Y is implied once Z and X are known. Breaking it would -// add a facet and buy nothing. -// -// KNOWN AMBIGUITY, stated rather than hidden: viewed exactly ALONG the ridge (+/-X, -// orthographic), the silhouette is the same isoceles triangle from front and back. Front -// and back are then distinguished by SHADING only — the long shallow front face catches -// light differently from the steep back face. If the target renderer is flat-shaded with a -// single headlight, verify this case before committing to the shape. - -// ---------------------------------------------------------------- parameters -L = 12.0; // overall length along the ridge (X) -W = 4.0; // half-width at the BACK -tf = 0.45; // front taper: front half-width = W * tf -H = 4.5; // peak height at the rear <-- the single dimension controlling asymmetry -pr = 0.22; // rear ridge position, fraction of L from the back -pf = 0.62; // front ridge position, fraction of L from the back -hf = 0.35; // front ridge height, fraction of H - -// Clearance is a PHYSICAL quantity and only means anything if this is a printed part. -// See the note at the bottom: for a viewport glyph it is meaningless. -clr = 0.20; // per-face clearance, mm -depth = 0.40; // extra pocket depth so the male never bottoms out before it seats - -Wf = W * tf; -xr0 = -L/2 + L * pr; -xr1 = -L/2 + L * pf; -Hf = H * hf; - -// ---------------------------------------------------------------- geometry -// Vertex order is fixed and referenced by the face table; do not reorder. -// 0 back-left 1 back-right 2 front-right 3 front-left -// 4 REAR PEAK (tall) 5 front ridge (low) -function ridge_pts(l, w, wf, h, hfr, x0, x1) = [ - [-l/2, -w, 0 ], // 0 - [-l/2, w, 0 ], // 1 - [ l/2, wf, 0 ], // 2 - [ l/2, -wf, 0 ], // 3 - [ x0, 0, h ], // 4 rear peak - [ x1, 0, hfr] // 5 front ridge, low -]; - -// OpenSCAD wants each face wound CLOCKWISE seen from OUTSIDE. The right-hand-rule -// outward-normal (CCW) form is given in the comment for anyone porting to STL/OCC, -// where the opposite convention is the usual one. -RIDGE_FACES = [ - [3, 2, 1, 0], // base (CCW-outward: [0,1,2,3]) planar, all z=0 - [1, 4, 0], // back (CCW-outward: [0,4,1]) steep - [5, 3, 0], // flank -Y a (CCW-outward: [0,3,5]) - [4, 5, 0], // flank -Y b (CCW-outward: [0,5,4]) - [5, 4, 1], // flank +Y a (CCW-outward: [1,4,5]) - [2, 5, 1], // flank +Y b (CCW-outward: [1,5,2]) - [5, 2, 3] // front (CCW-outward: [3,2,5]) long, shallow -]; - -module ridge_key(l = L, w = W, wf = Wf, h = H, hfr = Hf, x0 = xr0, x1 = xr1) { - polyhedron(points = ridge_pts(l, w, wf, h, hfr, x0, x1), - faces = RIDGE_FACES, - convexity = 3); -} - -// MALE: the protrusion, nominal size. -module ridge_key_male() { ridge_key(); } - -// FEMALE: the pocket. Grown by `clr` on every side and sunk `depth` deeper. -// -// HONEST LIMITATION: this grows the key by scaling its defining dimensions, which is NOT a -// true uniform surface offset — on the shallow front face the normal clearance comes out -// smaller than `clr`, because that face is far from perpendicular to every axis it is -// scaled along. A true offset needs minkowski() with a small cube, which is exact and slow, -// or an explicit per-face plane push, which is exact and fiddly. For a keying feature whose -// job is angular registration rather than a press fit, the approximation is the right trade -// — but do not quote this pocket as holding 0.2 mm everywhere, because it does not. -module ridge_key_female() { - translate([0, 0, -depth]) - ridge_key(l = L + 2*clr, - w = W + clr, - wf = Wf + clr, - h = H + clr + depth, - hfr = Hf + clr + depth, - x0 = xr0, - x1 = xr1); -} - -// ---------------------------------------------------------------- demo -// Left: the male key on its plate. Right: the plate with the pocket cut. -PLATE = [30, 18, 3]; - -module plate_with_male() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_male(); -} - -module plate_with_female() { - difference() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_female(); - } -} - -translate([-20, 0, 0]) plate_with_male(); -translate([ 20, 0, 0]) plate_with_female(); - -// ---------------------------------------------------------------- note on the two readings -// This file is written for the PHYSICAL reading: a printable alignment key, where `clr` and -// `depth` are real millimetres and flat facets genuinely help — they slice without the -// stair-stepping a tessellated curve produces, and they print without support on the -// shallow front face. -// -// If the intent is instead the VIEWPORT GLYPH for a CAD mate connector, then: -// - `clr` and `depth` are meaningless: a symbol does not mate with anything; -// - all dimensions must become SCREEN PIXELS scaled by upp = 1/zoom, because every gizmo -// in that viewport is screen-constant and must not shrink with the model; -// - "low-poly for rendering performance" is not a real reason at ~2-20 glyphs per frame. -// The real reason to keep flat facets there is LEGIBILITY: hard normals give distinct -// value steps between facets, and that is what lets a 22-px solid read as an oriented -// object instead of a grey blob. -// The vertex logic above is identical under both readings. Only the units and the clearance -// change. diff --git a/docs/CAD/design/mate-connectors/fem-0.png b/docs/CAD/design/mate-connectors/fem-0.png deleted file mode 100644 index 391881e72a..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-1.png b/docs/CAD/design/mate-connectors/fem-1.png deleted file mode 100644 index c329d20bea..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-2.png b/docs/CAD/design/mate-connectors/fem-2.png deleted file mode 100644 index a32f2ffbf1..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-3.png b/docs/CAD/design/mate-connectors/fem-3.png deleted file mode 100644 index f21ae3f98b..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-3.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-sheet.png b/docs/CAD/design/mate-connectors/fem-sheet.png deleted file mode 100644 index add56590a1..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/fem-sheet2.png b/docs/CAD/design/mate-connectors/fem-sheet2.png deleted file mode 100644 index 879b4295fb..0000000000 Binary files a/docs/CAD/design/mate-connectors/fem-sheet2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/female.stl b/docs/CAD/design/mate-connectors/female.stl deleted file mode 100644 index 57b0ef6d20..0000000000 --- a/docs/CAD/design/mate-connectors/female.stl +++ /dev/null @@ -1,226 +0,0 @@ -solid OpenSCAD_Model - facet normal 1 -0 0 - outer loop - vertex 15 -9 0 - vertex 15 9 -8 - vertex 15 9 0 - endloop - endfacet - facet normal 1 0 0 - outer loop - vertex 15 9 -8 - vertex 15 -9 0 - vertex 15 -9 -8 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex 5.3246 1.63218 0 - vertex 15 -9 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex -4.79494 3.42759 0 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 15 9 0 - vertex -5.97725 3.87059 0 - vertex -4.79494 3.42759 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -5.97725 3.87059 0 - vertex -15 9 0 - vertex -5.97725 -3.87059 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -15 9 0 - vertex -5.97725 3.87059 0 - vertex 15 9 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex 5.3246 -1.63218 0 - vertex 15 -9 0 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -4.79494 -3.42759 0 - vertex 15 -9 0 - vertex 5.3246 -1.63218 0 - endloop - endfacet - facet normal -0 0 1 - outer loop - vertex -5.97725 -3.87059 0 - vertex 15 -9 0 - vertex -4.79494 -3.42759 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -5.97725 -3.87059 0 - vertex -15 -9 0 - vertex 15 -9 0 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -15 -9 0 - vertex -5.97725 -3.87059 0 - vertex -15 9 0 - endloop - endfacet - facet normal 0 0 -1 - outer loop - vertex -15 -9 -8 - vertex 15 9 -8 - vertex 15 -9 -8 - endloop - endfacet - facet normal -0 0 -1 - outer loop - vertex 15 9 -8 - vertex -15 -9 -8 - vertex -15 9 -8 - endloop - endfacet - facet normal -1 0 0 - outer loop - vertex -15 -9 -8 - vertex -15 9 0 - vertex -15 9 -8 - endloop - endfacet - facet normal -1 -0 0 - outer loop - vertex -15 9 0 - vertex -15 -9 -8 - vertex -15 -9 0 - endloop - endfacet - facet normal 0 1 -0 - outer loop - vertex 15 9 -8 - vertex -15 9 0 - vertex 15 9 0 - endloop - endfacet - facet normal 0 1 0 - outer loop - vertex -15 9 0 - vertex 15 9 -8 - vertex -15 9 -8 - endloop - endfacet - facet normal 0 -1 0 - outer loop - vertex -15 -9 -8 - vertex 15 -9 0 - vertex -15 -9 0 - endloop - endfacet - facet normal 0 -1 -0 - outer loop - vertex 15 -9 0 - vertex -15 -9 -8 - vertex 15 -9 -8 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex -6.2 4.2 -0.4 - vertex 6.2 -2 -0.4 - vertex 6.2 2 -0.4 - endloop - endfacet - facet normal 0 0 1 - outer loop - vertex 6.2 -2 -0.4 - vertex -6.2 4.2 -0.4 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal 0.873667 0 -0.486524 - outer loop - vertex -5.97725 -3.87059 0 - vertex -6.2 4.2 -0.4 - vertex -5.97725 3.87059 0 - endloop - endfacet - facet normal 0.873667 0 -0.486524 - outer loop - vertex -6.2 4.2 -0.4 - vertex -5.97725 -3.87059 0 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal -0.107146 0.603912 -0.789816 - outer loop - vertex 6.2 -2 -0.4 - vertex -4.79494 -3.42759 0 - vertex 5.3246 -1.63218 0 - endloop - endfacet - facet normal -0.107147 0.603918 -0.789812 - outer loop - vertex -4.79494 -3.42759 0 - vertex 6.2 -2 -0.4 - vertex -6.2 -4.2 -0.4 - endloop - endfacet - facet normal -0.304068 0.811519 -0.498978 - outer loop - vertex -4.79494 -3.42759 0 - vertex -6.2 -4.2 -0.4 - vertex -5.97725 -3.87059 0 - endloop - endfacet - facet normal -0.304068 -0.811519 -0.498978 - outer loop - vertex -5.97725 3.87059 0 - vertex -6.2 4.2 -0.4 - vertex -4.79494 3.42759 0 - endloop - endfacet - facet normal -0.107146 -0.603912 -0.789816 - outer loop - vertex -4.79494 3.42759 0 - vertex 6.2 2 -0.4 - vertex 5.3246 1.63218 0 - endloop - endfacet - facet normal -0.107147 -0.603918 -0.789812 - outer loop - vertex 6.2 2 -0.4 - vertex -4.79494 3.42759 0 - vertex -6.2 4.2 -0.4 - endloop - endfacet - facet normal -0.415603 0 -0.909546 - outer loop - vertex 5.3246 -1.63218 0 - vertex 6.2 2 -0.4 - vertex 6.2 -2 -0.4 - endloop - endfacet - facet normal -0.415603 0 -0.909546 - outer loop - vertex 6.2 2 -0.4 - vertex 5.3246 -1.63218 0 - vertex 5.3246 1.63218 0 - endloop - endfacet -endsolid OpenSCAD_Model diff --git a/docs/CAD/design/mate-connectors/female_only.scad b/docs/CAD/design/mate-connectors/female_only.scad deleted file mode 100644 index 89f83b4655..0000000000 --- a/docs/CAD/design/mate-connectors/female_only.scad +++ /dev/null @@ -1,12 +0,0 @@ -// Female half alone, for the legibility test: is a recessed faceted pocket readable in a -// shaded view, or does a concave feature just read as a dark hole with no orientation? -use - -// The plate must be THICKER than the key is tall, or the "pocket" is a through-hole. The -// first version used 3 mm against a 4.5 mm key and cut straight through — caught only by -// rendering it. Minimum stock = H + clearance + pocket depth + a wall to print against. -PLATE = [30, 18, 8]; -difference() { - translate([-PLATE[0]/2, -PLATE[1]/2, -PLATE[2]]) cube(PLATE); - ridge_key_female(); -} diff --git a/docs/CAD/design/mate-connectors/fit_check.py b/docs/CAD/design/mate-connectors/fit_check.py deleted file mode 100644 index 5a9ee01063..0000000000 --- a/docs/CAD/design/mate-connectors/fit_check.py +++ /dev/null @@ -1,20 +0,0 @@ -# Measure the assembled fit between the supplied male and the generated female. -# This is the number that matters: the minimum gap in the seated position. -# Run: /snap/bin/freecad.cmd fit_check.py -import os -import Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -male = Part.Shape(); male.read(os.path.join(HERE, "bear.step")) -fem = Part.Shape(); fem.read(os.path.join(HERE, "BearConnector_Female.step")) -male, fem = male.Solids[0], fem.Solids[0] - -d = male.distToShape(fem) -print(f"RESULT minimum gap male<->female, seated: {d[0]:.4f} mm (design clearance 0.20)") - -c = male.common(fem) -print(f"RESULT interference volume: {(c.Volume if c.Solids else 0.0):.6f} mm3") - -p = d[1][0][0] -print(f"RESULT tightest point on the male: ({p.x:.2f}, {p.y:.2f}, {p.z:.2f})") -print(f"RESULT male {male.Volume/1000:.2f} cm3 / female {fem.Volume/1000:.2f} cm3") diff --git a/docs/CAD/design/mate-connectors/glyph-preview.png b/docs/CAD/design/mate-connectors/glyph-preview.png deleted file mode 100644 index 5e62c9a17f..0000000000 Binary files a/docs/CAD/design/mate-connectors/glyph-preview.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/glyph_preview.py b/docs/CAD/design/mate-connectors/glyph_preview.py deleted file mode 100644 index e339e6bdab..0000000000 --- a/docs/CAD/design/mate-connectors/glyph_preview.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Render the SIMPLIFIED glyph exactly as render_mate_face() draws it — x0kd. - -This is the panel the study was missing. simplify_study.py measured a FLAT outline and -relief_sheet.py measured the FULL 1508-facet part; neither showed the simplified glyph WITH its -relief, which is what the code actually draws and the only thing that answers "is the snout still -protruding". Same facet list, same painter order, same camera-fixed lambert as the C++. -""" -import math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -T = open(os.path.join(HERE, "bear_glyph_table.h")).read() -def grab(name, n): - body = T.split(name + "[] = {")[1].split("};")[0] - body = "\n".join(l.split("//")[0] for l in body.splitlines()) - out = [] - for tok in body.replace("\n", " ").split("},"): - tok = tok.strip().lstrip("{").strip() - if not tok: continue - v = [float(x) for x in tok.replace("{", "").split(",")[:n]] - if len(v) == n: out.append(tuple(v)) - return out -OUT = grab("kBearOutline", 2) -CHIN = grab("kBearChin", 2) # NB: this table entry is the CHIN BAR, not the snout -MARKS = grab("kBearMarks", 3) -CREST = grab("kBearCrest", 3) -SBASE = grab("kBearSnoutBase", 2) -PLATE = float(T.split("kBearPlateZ = ")[1].split(";")[0]) - - -def facets(): - F = [] - n = len(OUT) - for i in range(n): # plate sides -> the grazing silhouette - a, b = OUT[i], OUT[(i+1) % n] - F.append(([(a[0],a[1],0.0),(b[0],b[1],0.0),(b[0],b[1],PLATE),(a[0],a[1],PLATE)], "body", True)) - F.append(([(x,y,PLATE) for x,y in OUT], "body", True)) # plate top - zm = PLATE + 0.004 - for cx,cy,r in MARKS: # eyes + cheek dot - F.append(([(cx+r*math.cos(2*math.pi*i/12), cy+r*math.sin(2*math.pi*i/12), zm) for i in range(12)], "mark", False)) - F.append(([(x,y,zm) for x,y in CHIN], "mark", False)) # chin bar - A, B = CREST # THE MUZZLE: base quad + crest - nl=(SBASE[0][0],SBASE[0][1],PLATE); nr=(SBASE[1][0],SBASE[1][1],PLATE) - tr=(SBASE[2][0],SBASE[2][1],PLATE); tl=(SBASE[3][0],SBASE[3][1],PLATE) - F += [([nl,tl,B,A],"body",True), # left flank - ([nr,A,B,tr],"body",True), # right flank - ([nl,A,nr],"body",True), # nose cap, sloping because the base overhangs the crest - ([tr,B,tl],"body",True)] # tail cap - return F -FACETS = facets() - -BODY=(0.42,0.46,0.52); MARK=(0.126,0.138,0.156) -def render(px, elev_deg, ss=8): - S=px*ss; a=math.radians(elev_deg); ca,sa=math.cos(a),math.sin(a) - # camera orbits down; the connector's +Z (relief) tips toward the horizon - xf=lambda p:(p[0], p[1]*sa + p[2]*ca, -p[1]*ca + p[2]*sa) - light=(-0.70,0.30,0.45) - img=Image.new("RGB",(S,S),(24,27,32)); d=ImageDraw.Draw(img) - tris=[] - for pts,kind,shade in FACETS: - q=[xf(p) for p in pts] - tris.append((sum(v[2] for v in q)/len(q), q, kind, shade)) - tris.sort(key=lambda t:t[0]) # far first - for _,q,kind,shade in tris: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2)=q[0],q[1],q[2] - ux,uy,uz=x1-x0,y1-y0,z1-z0; vx,vy,vz=x2-x0,y2-y0,z2-z0 - nx,ny,nz=uy*vz-uz*vy, uz*vx-ux*vz, ux*vy-uy*vx - nn=math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0 - nx,ny,nz=nx/nn,ny/nn,nz/nn - if nz<0: nx,ny,nz=-nx,-ny,-nz - base=BODY if kind=="body" else MARK - k=(0.42+0.58*max(0.0,nx*light[0]+ny*light[1]+nz*light[2])) if shade else 1.0 - col=tuple(min(255,int(255*c*k)) for c in base) - d.polygon([(S/2+p[0]*S*0.92, S/2-p[1]*S*0.92) for p in q], fill=col) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48]; ELEVS=[(90,"flat on"),(47,"47"),(16,"16"),(6,"6")] -pad,cell=8,58 -W=pad+len(SIZES)*len(ELEVS)*cell+pad; H=pad+cell+pad -sheet=Image.new("RGB",(W,H),(24,27,32)) -for ci,(e,_) in enumerate(ELEVS): - for si,px in enumerate(SIZES): - g=render(px,e) - sheet.paste(g, (pad+(ci*len(SIZES)+si)*cell+(cell-px)//2, pad+(cell-px)//2)) -sheet.resize((W*2,H*2), Image.NEAREST).save(os.path.join(HERE,"glyph-preview.png")) - -# how much of the glyph is the snout: render with and without the tent and diff -def render_no_tent(px, elev): - global FACETS - keep=FACETS; FACETS=FACETS[:-4] - try: return render(px, elev) - finally: FACETS=keep -print(f"{'elev':>8} {'lit px@32':>10} {'snout px':>9} {'snout share':>12}") -for e,_ in ELEVS: - a=render(32,e); b=render_no_tent(32,e) - la=sum(1 for p in a.get_flattened_data() if p!=(24,27,32)) - diff=sum(1 for p,q in zip(a.get_flattened_data(), b.get_flattened_data()) if p!=q) - print(f"{e:>8} {la:>10} {diff:>9} {100.0*diff/max(1,la):>11.1f}%") -print("WROTE glyph-preview.png") diff --git a/docs/CAD/design/mate-connectors/glyph_probe.py b/docs/CAD/design/mate-connectors/glyph_probe.py deleted file mode 100644 index f4d48fdd6c..0000000000 --- a/docs/CAD/design/mate-connectors/glyph_probe.py +++ /dev/null @@ -1,143 +0,0 @@ -# Mate-connector glyph probe — built as REAL solids on REAL mechanical geometry, -# so the shape can be judged in a 3D viewport instead of in a browser mock. -# -# Four polarity treatments, side by side on one bracket: -# A Onshape baseline ...... ring + roll quadrant + three short axis arms -# B solid cone ............ ring + quadrant + one-sided Z arrow, filled head (driven) -# C hollow collar ......... ring + quadrant + one-sided Z arrow, shell head (fixed) -# D pin / cup ............. polarity by RELIEF: a raised pin vs a sunk cup -# -# D is the one that only a 3D test can settle: in a shaded viewport, solid-vs-hollow is a -# weak cue that depends on angle and lighting, while convex-vs-concave is a strong one -- -# and male/female is the mechanical language for polarity anyway. -# -# Scale note: in the real viewport gizmos are screen-constant (~15-40 px via upp = 1/zoom). -# At a zoom where a 60 mm part fills ~600 px, 40 px is about 4 mm, so R = 4.5 mm here. - -import FreeCAD as App -import FreeCADGui as Gui -import Part -from FreeCAD import Vector - -DOC = "GlyphProbe" -for d in list(App.listDocuments()): - App.closeDocument(d) -doc = App.newDocument(DOC) - -R = 4.5 # disc radius, the module everything scales from -GOLD = (0.93, 0.66, 0.09) -BLUE = (0.18, 0.44, 0.93) -GREY = (0.42, 0.46, 0.52) -RED = (0.85, 0.29, 0.24) -GREEN = (0.23, 0.65, 0.35) - -def add(name, shape, color, transparency=0): - o = doc.addObject("Part::Feature", name) - o.Shape = shape - o.ViewObject.ShapeColor = color - o.ViewObject.LineColor = color - o.ViewObject.PointColor = color - o.ViewObject.Transparency = transparency - return o - -def frame(origin, zdir, xdir): - """Right-handed placement matrix from origin + Z + X (X orthonormalised against Z).""" - z = Vector(*zdir); z.normalize() - xr = Vector(*xdir) - x = xr.sub(Vector(z).multiply(z.dot(xr))); x.normalize() - y = z.cross(x) - return App.Matrix(x.x, y.x, z.x, origin[0], - x.y, y.y, z.y, origin[1], - x.z, y.z, z.z, origin[2], - 0, 0, 0, 1) - -# ---------------------------------------------------------------- the bracket -plate = Part.makeBox(120, 46, 8) -bore = Part.makeCylinder(7, 40, Vector(96, 23, -6)) # a real bore, curved face -boss = Part.makeCylinder(11, 7, Vector(96, 23, 8)) -part = plate.fuse(boss).cut(bore) -add("Bracket", part, (0.60, 0.63, 0.66)) - -# ---------------------------------------------------------------- glyph pieces -def ring(t=None): - t = t or R * 0.10 - return Part.makeCylinder(R, t).cut(Part.makeCylinder(R * 0.84, t)) - -def quadrant(t=None): - t = t or R * 0.10 - return Part.makeCylinder(R * 0.84, t, Vector(0, 0, 0), Vector(0, 0, 1), 90) - -def stem(L=None, r=None): - return Part.makeCylinder(r or R * 0.09, L or R * 2.3) - -def solid_head(): - return Part.makeCone(R * 0.32, 0, R * 0.80, Vector(0, 0, R * 2.3)) - -def shell_head(): - outer = Part.makeCone(R * 0.32, 0, R * 0.80, Vector(0, 0, R * 2.3)) - inner = Part.makeCone(R * 0.22, 0, R * 0.62, Vector(0, 0, R * 2.3)) - return outer.cut(inner) - -def short_axis(direction, L=None): - L = L or R * 1.15 - return Part.makeCylinder(R * 0.07, L, Vector(0, 0, 0), Vector(*direction)) - -def place(shape, m): - s = shape.copy() - s.transformShape(m) - return s - -# ---------------------------------------------------------------- the variants -def variant_A(tag, origin): # Onshape baseline - m = frame(origin, (0, 0, 1), (1, 0, 0)) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_x", place(short_axis((1, 0, 0)), m), RED) - add(tag + "_y", place(short_axis((0, 1, 0)), m), GREEN) - add(tag + "_z", place(short_axis((0, 0, 1), R * 1.6), m), BLUE) - -def variant_B(tag, origin, zdir=(0, 0, 1)): # solid cone = driven - m = frame(origin, zdir, (1, 0, 0)) - add(tag + "_ring", place(ring(), m), BLUE) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_body", place(stem().fuse(solid_head()), m), BLUE) - -def variant_C(tag, origin, zdir=(0, 0, 1)): # hollow collar = fixed - m = frame(origin, zdir, (1, 0, 0)) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_body", place(stem().fuse(shell_head()), m), GREY) - -def variant_D_pin(tag, origin, zdir=(0, 0, 1)): # polarity by relief: raised PIN - m = frame(origin, zdir, (1, 0, 0)) - pin = Part.makeCylinder(R * 0.30, R * 1.5).fuse( - Part.makeCone(R * 0.30, 0, R * 0.55, Vector(0, 0, R * 1.5))) - add(tag + "_ring", place(ring(), m), BLUE) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_pin", place(pin, m), BLUE) - -def variant_D_cup(tag, origin, zdir=(0, 0, 1)): # polarity by relief: sunk CUP - m = frame(origin, zdir, (1, 0, 0)) - cup = Part.makeCylinder(R * 0.62, R * 0.9).cut( - Part.makeCylinder(R * 0.40, R * 0.9, Vector(0, 0, -0.01))) - add(tag + "_ring", place(ring(), m), GREY) - add(tag + "_quad", place(quadrant(), m), GOLD) - add(tag + "_cup", place(cup, m), GREY) - -# four treatments across the plate, all on the same flat face, same Z -variant_A("A", (14, 30, 8)) -variant_B("B", (40, 30, 8)) -variant_C("C", (64, 30, 8)) -variant_D_pin("Dpin", (14, 10, 8)) -variant_D_cup("Dcup", (40, 10, 8)) - -# the hard cases, which is the whole reason for doing this in 3D: -variant_B("Bore", (96, 23, 15)) # on the boss above a bore -variant_B("Edge", (64, 0, 8), (0, -0.7071, 0.7071)) # tilted, on an edge, oblique Z - -doc.recompute() - -v = Gui.activeDocument().activeView() -v.viewIsometric() -Gui.SendMsgToActiveView("ViewFit") -App.Console.PrintMessage("glyph probe built: %d objects\n" % len(doc.Objects)) diff --git a/docs/CAD/design/mate-connectors/handedness-sheet.png b/docs/CAD/design/mate-connectors/handedness-sheet.png deleted file mode 100644 index b44c370328..0000000000 Binary files a/docs/CAD/design/mate-connectors/handedness-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/handedness.py b/docs/CAD/design/mate-connectors/handedness.py deleted file mode 100644 index 68fa07bb55..0000000000 --- a/docs/CAD/design/mate-connectors/handedness.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Give the bear a handedness mark that survives rasterisation — wi3z, Tommaso's call 2. - -The study showed the left/right cue lives in sub-millimetre corner radii and is therefore invisible -at glyph size: one pixel is 2.6 mm at 32 px. Roll and verse are safe; handedness is not. - -THE MEASURE IS THE QUESTION ITSELF. Render the glyph, render its mirror image, and count how many -pixels differ. If a human is to tell left from right, the two must differ on screen; a candidate -that scores near zero is invisible however elegant it looks in CAD. Reported as a percentage of the -glyph's own lit area, so the sizes are comparable. -""" -import json, math, os -from PIL import Image, ImageDraw, ImageChops - -HERE = os.path.dirname(os.path.abspath(__file__)) -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) -def unit(pts): - p = [(x, -z) for x, z in pts] - return p -outer = unit(D["outer"]); holes = [unit(h["pts"]) for h in D["holes"]] -ALL = outer + [p for h in holes for p in h] -xs=[p[0] for p in ALL]; ys=[p[1] for p in ALL] -CX,CY = (min(xs)+max(xs))/2,(min(ys)+max(ys))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -U = lambda pts: [((x-CX)/SPAN,(y-CY)/SPAN) for x,y in pts] -OUT = U(outer) -EYES = [U(h) for h,m in zip(holes, D["holes"]) if m["d"] < 20] -MUZ = U([h for h,m in zip(holes, D["holes"]) if m["d"] >= 20][0]) - -def rdp(pts, eps): - if len(pts) < 3: return pts - ax,ay=pts[0]; bx,by=pts[-1]; dx,dy=bx-ax,by-ay - n=math.hypot(dx,dy); best,bi=-1.0,0 - for i in range(1,len(pts)-1): - px,py=pts[i] - d=abs(dx*(ay-py)-(ax-px)*dy)/n if n>1e-12 else math.hypot(px-ax,py-ay) - if d>best: best,bi=d,i - if best<=eps: return [pts[0],pts[-1]] - return rdp(pts[:bi+1],eps)[:-1]+rdp(pts[bi:],eps) -def simp(pts,eps): - r=rdp(pts+[pts[0]],eps); return r[:-1] - -BASE = simp(OUT, .030) # the 22-vertex outline the study settled on -def centroid(p): return (sum(q[0] for q in p)/len(p), sum(q[1] for q in p)/len(p)) -def circ(cx,cy,r,n=16): return [(cx+r*math.cos(2*math.pi*i/n), cy+r*math.sin(2*math.pi*i/n)) for i in range(n)] -EYE_D = [] -for e in EYES: - c=centroid(e); r=(max(p[0] for p in e)-min(p[0] for p in e))/2 - EYE_D.append((c[0],c[1],r)) -EYE_D.sort() # [0] = left (x<0), [1] = right - -TOP = max(p[1] for p in BASE) -H = TOP - min(p[1] for p in BASE) -def ear_tip(sign): - cands=[p for p in BASE if p[1] > TOP-0.18*H and (p[0]*sign) > 0] - return max(cands, key=lambda p: p[0]*sign) if cands else None -LT, RT = ear_tip(-1), ear_tip(+1) - -def notch(tip, sign, k=0.085): - """A wedge bitten out of one ear — background-filled, exactly how the eyes are already drawn.""" - x,y = tip - return [(x, y+0.02), (x - sign*k, y - k*0.55), (x + sign*k*0.15, y - k*1.05)] - -CANDS = { - "H0 none": dict(cuts=[], eyes=EYE_D), - "H1 notch R ear": dict(cuts=[notch(RT, +1)], eyes=EYE_D), - "H2 notch both": dict(cuts=[notch(RT, +1), notch(LT, -1, 0.045)], eyes=EYE_D), - "H3 cheek dot": dict(cuts=[circ(EYE_D[1][0]+0.085, EYE_D[1][1]-0.10, 0.038)], eyes=EYE_D), - "H4 uneven eyes": dict(cuts=[], eyes=[EYE_D[0], (EYE_D[1][0], EYE_D[1][1], EYE_D[1][2]*1.55)]), -} - -def render(c, px, ss=8, mirror=False): - S=px*ss; img=Image.new("L",(S,S),0); d=ImageDraw.Draw(img) - m = lambda p: (S/2 + (-p[0] if mirror else p[0])*S*0.92, S/2 - p[1]*S*0.92) - d.polygon([m(p) for p in BASE], fill=255) - d.polygon([m(p) for p in MUZ], fill=0) - for cx,cy,r in c["eyes"]: - a=m((cx-r,cy+r)); b=m((cx+r,cy-r)) - d.ellipse([min(a[0],b[0]), min(a[1],b[1]), max(a[0],b[0]), max(a[1],b[1])], fill=0) - for cut in c["cuts"]: - d.polygon([m(p) for p in cut], fill=0) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48] -print(f"{'candidate':16} " + " ".join(f"{s}px" for s in SIZES) + " (pixels differing from own mirror, % of lit area)") -print("-"*84) -scores={} -for name,c in CANDS.items(): - row=[] - for px in SIZES: - a=render(c,px); b=render(c,px,mirror=True) - diff=ImageChops.difference(a,b) - nd=sum(1 for v in diff.getdata() if v>40) - lit=sum(1 for v in a.getdata() if v>40) or 1 - row.append(100.0*nd/lit) - scores[name]=row - print(f"{name:16} " + " ".join(f"{v:5.1f}" for v in row)) - -pad,cell=8,58 -W=pad+len(SIZES)*2*cell+pad; Hh=pad+len(CANDS)*cell+pad -sheet=Image.new("RGB",(W,Hh),(24,27,32)) -for r,(name,c) in enumerate(CANDS.items()): - for mi,mir in enumerate((False,True)): - for si,px in enumerate(SIZES): - g=render(c,px,mirror=mir) - tile=Image.new("RGB",(px,px),(24,27,32)) - tile.paste(Image.new("RGB",(px,px),(237,168,23)),(0,0),g) - x=pad+(mi*len(SIZES)+si)*cell+(cell-px)//2 - y=pad+r*cell+(cell-px)//2 - sheet.paste(tile,(x,y)) -sheet.resize((W*2,Hh*2), Image.NEAREST).save(os.path.join(HERE,"handedness-sheet.png")) -print("\nleft block = as drawn, right block = mirrored. rows: " + ", ".join(CANDS)) -print("WROTE handedness-sheet.png") diff --git a/docs/CAD/design/mate-connectors/linearedgemateconnectors.png b/docs/CAD/design/mate-connectors/linearedgemateconnectors.png deleted file mode 100644 index fd5e64190d..0000000000 Binary files a/docs/CAD/design/mate-connectors/linearedgemateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/make_female.py b/docs/CAD/design/mate-connectors/make_female.py deleted file mode 100644 index ccb38426bf..0000000000 --- a/docs/CAD/design/mate-connectors/make_female.py +++ /dev/null @@ -1,135 +0,0 @@ -# Build the complementary FEMALE for BearConnector.step. -# -# Method: take the supplied male B-rep as-is, grow it by a uniform clearance, and subtract that -# from a block. Working on the real solid rather than re-modelling the bear is the whole point — -# the pocket is then exactly complementary by construction, including every deliberate asymmetry. -# -# The offset uses join=2 (Intersection), which extends the adjacent planes and meets them at a -# sharp corner. For a faceted part that is the correct join: the arc join would round every convex -# edge and blunt the very cues the design depends on. -# -# THE MALE'S NATIVE FRAME: the flat back is the plane Y=0 and the relief rises to Y=+17.27. -# X and Z carry the face (83.34 x 66.69). The frame is kept exactly as supplied so that male and -# female drop into the same assembly without anyone having to re-orient one of them. -# Insertion is therefore along +Y, and the pocket must OPEN on the Y=0 plane. -# -# A first version of this script assumed the relief ran along +Z, built the block around the wrong -# axis, and produced a sealed cavity with no way in. It passed a "male does not intersect female" -# check, because that only tests the seated position and says nothing about whether the part can -# get there. The straight-pull test below is what catches it. -# -# Run: /snap/bin/freecad.cmd make_female.py - -import os, sys, math -import FreeCAD as App -import Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -OUT_STEP = os.path.join(HERE, "BearConnector_Female.step") - -CLEAR = 0.20 # per-face clearance, mm -WALL = 4.0 # material around the pocket, mm -FLOOR = 3.0 # material behind the deepest point of the pocket, mm - -male = Part.Shape(); male.read(MALE) -if len(male.Solids) != 1: - print(f"FAIL: expected 1 solid in the male, found {len(male.Solids)}"); sys.exit(1) -male = male.Solids[0] -bb = male.BoundBox -print(f"male : {bb.XLength:.2f} (X) x {bb.YLength:.2f} (Y) x {bb.ZLength:.2f} (Z) mm, " - f"{len(male.Faces)} faces, {male.Volume/1000:.2f} cm3") -print(f" relief runs Y {bb.YMin:.2f} .. {bb.YMax:.2f} -> insertion along +Y, mouth at Y={bb.YMin:.2f}") - -# ---- 1. can the male even be withdrawn along the insertion axis? ---------------------- -# Ray-cast a grid along +Y through the tessellated male and count crossings. A straight pull is -# possible only if no ray enters the solid more than once; a second entry is an undercut. -verts, facets = male.tessellate(0.15) -V = [(v.x, v.y, v.z) for v in verts] -worst, undercut_pts = 0, 0 -NX = NZ = 90 -for i in range(NX): - x = bb.XMin + (i + 0.5) * bb.XLength / NX - for j in range(NZ): - z = bb.ZMin + (j + 0.5) * bb.ZLength / NZ - hits = 0 - for (ia, ib, ic) in facets: # ray (x, *, z) along +Y vs triangle - ax, ay, az = V[ia]; bx, by, bz = V[ib]; cx, cy, cz = V[ic] - # 2D point-in-triangle in the XZ plane - d = (bz - cz) * (ax - cx) + (cx - bx) * (az - cz) - if abs(d) < 1e-12: continue - u = ((bz - cz) * (x - cx) + (cx - bx) * (z - cz)) / d - v = ((cz - az) * (x - cx) + (ax - cx) * (z - cz)) / d - if u < 0 or v < 0 or u + v > 1: continue - hits += 1 - worst = max(worst, hits) - if hits > 2: undercut_pts += 1 -print(f"pull : max crossings along +Y = {worst}, undercut samples = {undercut_pts}/{NX*NZ}") -if undercut_pts: - print("FAIL: the male has an undercut along +Y; a straight pocket cannot release it") - sys.exit(1) -print(" no undercut -> a straight-pull pocket works") - -# ---- 2. grow the male by the clearance ----------------------------------------------- -grown = None -for join, name in ((2, "Intersection"), (1, "Tangent"), (0, "Arc")): - try: - g = male.makeOffsetShape(CLEAR, 1e-6, False, False, 0, join, False) - if g.isValid() and g.Solids: - grown = g.Solids[0]; print(f"offset: join={name}, {grown.Volume/1000:.2f} cm3"); break - except Exception as e: - print(f"offset: join={name} failed -- {e}") -if grown is None: - print("FAIL: could not offset the male; refusing to emit a zero-clearance pocket"); sys.exit(1) - -# ---- 3. the block: walls in X and Z, depth in +Y, OPEN at the Y=0 mouth --------------- -gb = grown.BoundBox -y_mouth = bb.YMin # the male's flat back plane -depth = gb.YMax - y_mouth -block = Part.makeBox(gb.XLength + 2*WALL, depth + FLOOR, gb.ZLength + 2*WALL, - App.Vector(gb.XMin - WALL, y_mouth, gb.ZMin - WALL)) -print(f"block : {gb.XLength + 2*WALL:.2f} x {depth + FLOOR:.2f} x {gb.ZLength + 2*WALL:.2f} mm, " - f"mouth on the Y={y_mouth:.2f} plane") - -female = block.cut(grown) - -# ---- 4. verify -------------------------------------------------------------------------- -ok = True -if not female.isValid(): print("FAIL: invalid shape"); ok = False -if len(female.Solids) != 1: print(f"FAIL: {len(female.Solids)} solids"); ok = False - -clash = male.common(female) -cv = clash.Volume if clash.Solids else 0.0 -print(f"check : male ∩ female = {cv:.6f} mm3 (seated fit, must be ~0)") -if cv > 1e-3: print("FAIL: male collides with female"); ok = False - -# the mouth must actually be open: the pocket has to reach the Y=y_mouth face of the block -mouth_face_area = 0.0 -for f in female.Faces: - c = f.CenterOfMass - if abs(c.y - y_mouth) < 1e-6: - mouth_face_area += f.Area -solid_mouth = (gb.XLength + 2*WALL) * (gb.ZLength + 2*WALL) -open_area = solid_mouth - mouth_face_area -print(f"check : mouth plane -- material {mouth_face_area:.1f} mm2, opening {open_area:.1f} mm2 " - f"({100*open_area/solid_mouth:.1f}% of the face)") -if open_area < 100: - print("FAIL: the pocket is sealed -- the male cannot be inserted"); ok = False - -cavity = block.Volume - female.Volume -print(f"check : cavity {cavity/1000:.2f} cm3 vs male {male.Volume/1000:.2f} cm3 " - f"-> clearance shell {(cavity-male.Volume)/1000:.2f} cm3") -if cavity < male.Volume: print("FAIL: cavity smaller than the male"); ok = False - -if not ok: - print("\nREFUSING to write the STEP"); sys.exit(1) - -doc = App.newDocument("Female") -obj = doc.addObject("Part::Feature", "BearConnector_Female") -obj.Shape = female -doc.recompute() -Part.export([obj], OUT_STEP) -fb = female.BoundBox -print(f"\nwrote {OUT_STEP}") -print(f"female: {fb.XLength:.2f} x {fb.YLength:.2f} x {fb.ZLength:.2f} mm, " - f"{len(female.Faces)} faces, {female.Volume/1000:.2f} cm3") diff --git a/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png b/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png deleted file mode 100644 index f9a80c1e10..0000000000 Binary files a/docs/CAD/design/mate-connectors/mate-connector-virtual-sharp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png b/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png deleted file mode 100644 index 16ca1c01e6..0000000000 Binary files a/docs/CAD/design/mate-connectors/mateconnector-planarcentroid.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png b/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png deleted file mode 100644 index d952ddc1f0..0000000000 Binary files a/docs/CAD/design/mate-connectors/mateconnector-planarpoints.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/matepointiconLG.png b/docs/CAD/design/mate-connectors/matepointiconLG.png deleted file mode 100644 index 2f3022d116..0000000000 Binary files a/docs/CAD/design/mate-connectors/matepointiconLG.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png b/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png deleted file mode 100644 index bd65a9f40e..0000000000 Binary files a/docs/CAD/design/mate-connectors/matepointreorientsecondaryaxis.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/muzzle_variants.py b/docs/CAD/design/mate-connectors/muzzle_variants.py deleted file mode 100644 index f4c9ab33b5..0000000000 --- a/docs/CAD/design/mate-connectors/muzzle_variants.py +++ /dev/null @@ -1,71 +0,0 @@ -"""The muzzle has to READ, not just be present — wi3z. - -Faithfully scaled, the part's ridge is 11.3 mm on an 83 mm face: 13.6 % of the width. At glyph -size that is a scratch. A glyph is a symbol, not a scale model, so the question is how much -emphasis it takes before the only +Z feature actually reads. Variants, all with the same crest -geometry, differing only in width and colour. -""" -import math, os, importlib.util -from PIL import Image, ImageDraw -spec=importlib.util.spec_from_file_location("gp","glyph_preview.py") -gp=importlib.util.module_from_spec(spec); spec.loader.exec_module(gp) - -OUT, CHIN, MARKS, CREST, SBASE, PLATE = gp.OUT, gp.CHIN, gp.MARKS, gp.CREST, gp.SBASE, gp.PLATE -BODY=(0.42,0.46,0.52); MARK=(0.126,0.138,0.156); GOLD=(0.93,0.66,0.09) - -def facets(widen=1.0, muzzle_gold=False): - F=[]; n=len(OUT) - for i in range(n): - a,b=OUT[i],OUT[(i+1)%n] - F.append(([(a[0],a[1],0.0),(b[0],b[1],0.0),(b[0],b[1],PLATE),(a[0],a[1],PLATE)],BODY,True)) - F.append(([(x,y,PLATE) for x,y in OUT],BODY,True)) - zm=PLATE+0.004 - for cx,cy,r in MARKS: - F.append(([(cx+r*math.cos(2*math.pi*i/12),cy+r*math.sin(2*math.pi*i/12),zm) for i in range(12)],MARK,False)) - F.append(([(x,y,zm) for x,y in CHIN],MARK,False)) - A,B=CREST - w=lambda p:(p[0]*widen,p[1],PLATE) - nl,nr,tr,tl=(w(SBASE[0]),w(SBASE[1]),w(SBASE[2]),w(SBASE[3])) - col = GOLD if muzzle_gold else BODY - F+=[([nl,tl,B,A],col,True),([nr,A,B,tr],col,True), - ([nl,A,nr],col,True), ([tr,B,tl],col,True)] - return F - -def render(F, px, elev, ss=8): - S=px*ss; a=math.radians(elev); ca,sa=math.cos(a),math.sin(a) - xf=lambda p:(p[0],p[1]*sa+p[2]*ca,-p[1]*ca+p[2]*sa) - light=(-0.70,0.30,0.45) - img=Image.new("RGB",(S,S),(24,27,32)); d=ImageDraw.Draw(img) - tris=sorted(((sum(v[2] for v in [xf(q) for q in pts])/len(pts),[xf(q) for q in pts],c,sh) - for pts,c,sh in F), key=lambda t:t[0]) - for _,q,base,shade in tris: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2)=q[0],q[1],q[2] - ux,uy,uz=x1-x0,y1-y0,z1-z0; vx,vy,vz=x2-x0,y2-y0,z2-z0 - nx,ny,nz=uy*vz-uz*vy,uz*vx-ux*vz,ux*vy-uy*vx - L=math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0; nx,ny,nz=nx/L,ny/L,nz/L - if nz<0: nx,ny,nz=-nx,-ny,-nz - k=(0.42+0.58*max(0.0,nx*light[0]+ny*light[1]+nz*light[2])) if shade else 1.0 - d.polygon([(S/2+p[0]*S*0.92,S/2-p[1]*S*0.92) for p in q], - fill=tuple(min(255,int(255*c*k)) for c in base)) - return img.resize((px,px),Image.LANCZOS) - -VAR=[("V1 faithful", 1.0, False), - ("V2 gold muzzle", 1.0, True), - ("V3 gold + 1.8x wide",1.8, True), - ("V4 body + 1.8x wide",1.8, False)] -big=Image.new("RGB",(4*250+30,4*140+30),(24,27,32)) -for r,(name,wd,gold) in enumerate(VAR): - F=facets(wd,gold) - for c,e in enumerate((90,47,16,6)): - big.paste(render(F,120,e),(15+c*250+60,15+r*140+10)) -big.save("/tmp/muzzle-variants.png") -for name,wd,gold in VAR: - F=facets(wd,gold); F0=[f for f in F][:-4] - row=[] - for e in (90,16,6): - a=render(F,32,e); b=render(F0,32,e) - la=sum(1 for p in a.get_flattened_data() if p!=(24,27,32)) - df=sum(1 for p,q in zip(a.get_flattened_data(),b.get_flattened_data()) if p!=q) - row.append(f"{100.0*df/max(1,la):5.1f}%") - print(f"{name:22} muzzle share at 90/16/6 deg: " + " ".join(row)) -print("WROTE /tmp/muzzle-variants.png") diff --git a/docs/CAD/design/mate-connectors/planarfacemateconnectors.png b/docs/CAD/design/mate-connectors/planarfacemateconnectors.png deleted file mode 100644 index 9fea27ab2b..0000000000 Binary files a/docs/CAD/design/mate-connectors/planarfacemateconnectors.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/relief-sheet.png b/docs/CAD/design/mate-connectors/relief-sheet.png deleted file mode 100644 index 0c6d0d11f0..0000000000 Binary files a/docs/CAD/design/mate-connectors/relief-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/relief_sheet.py b/docs/CAD/design/mate-connectors/relief_sheet.py deleted file mode 100644 index 4b8bc6aa74..0000000000 --- a/docs/CAD/design/mate-connectors/relief_sheet.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Flat glyph vs 3D relief, at the elevations that killed the disc — wi3z. - -The flat study collapsed at 16 deg because anything drawn IN the connector's plane foreshortens by -sin(elevation). This renders the SAME bear as its real relief (1508 facets off the supplied male) -with a simple lambert shade, so the silhouette does the work at a grazing angle. Two rows, same -sizes, same elevations, so the comparison is direct. -""" -import json, math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -M = json.load(open(os.path.join(HERE, "bear_mesh.json"))) -V, F = M["v"], M["f"] - -# Part frame: face carried by X (right) and Z (down-negative), relief along +Y. -P = [(v[0], -v[2], v[1]) for v in V] # -> (x right, y up, z out of the face) -xs=[p[0] for p in P]; ys=[p[1] for p in P]; zs=[p[2] for p in P] -CX,CY,CZ = (min(xs)+max(xs))/2, (min(ys)+max(ys))/2, (min(zs)+max(zs))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -P = [((x-CX)/SPAN, (y-CY)/SPAN, (z-CZ)/SPAN) for x,y,z in P] - -def shade(px, elev_deg, supersample=8): - """Camera orbits down from straight-on (90) to grazing (small). Rotate about the screen x-axis.""" - S = px*supersample - a = math.radians(elev_deg) - ca, sa = math.cos(a), math.sin(a) - # view: rotate the model so the face normal tips away from the camera - def xf(p): - x,y,z = p - return (x, y*sa + z*ca, -y*ca + z*sa) # third component = depth toward camera - Q = [xf(p) for p in P] - img = Image.new("L", (S,S), 0) - d = ImageDraw.Draw(img) - order = [] - for tri in F: - a3 = [Q[i] for i in tri] - order.append((sum(v[2] for v in a3)/3.0, tri, a3)) - order.sort(key=lambda t: t[0]) # painter: far first - light = (-0.35, 0.55, 0.76) - for _, tri, a3 in order: - (x0,y0,z0),(x1,y1,z1),(x2,y2,z2) = a3 - ux,uy,uz = x1-x0, y1-y0, z1-z0 - vx,vy,vz = x2-x0, y2-y0, z2-z0 - nx,ny,nz = uy*vz-uz*vy, uz*vx-ux*vz, ux*vy-uy*vx - n = math.sqrt(nx*nx+ny*ny+nz*nz) or 1.0 - nx,ny,nz = nx/n, ny/n, nz/n - if nz < 0: nx,ny,nz = -nx,-ny,-nz # face the camera - lam = max(0.0, nx*light[0] + ny*light[1] + nz*light[2]) - val = int(70 + 185*lam) - pts = [(S/2 + x*S*0.92, S/2 - y*S*0.92) for x,y,_ in a3] - d.polygon(pts, fill=val) - return img.resize((px,px), Image.LANCZOS) - -# flat outline, for the side-by-side -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) -def unit(pts): - p=[(x,-z) for x,z in pts] - return [((x-CX)/SPAN,(y-CY)/SPAN) for x,y in p] -OUT = unit(D["outer"]) -HOLES = [unit(h["pts"]) for h in D["holes"]] - -def flat(px, elev_deg, supersample=8): - S=px*supersample - img=Image.new("L",(S,S),0); d=ImageDraw.Draw(img) - k=math.sin(math.radians(elev_deg)) - m=lambda p:(S/2+p[0]*S*0.92, S/2-p[1]*S*0.92*k) - d.polygon([m(p) for p in OUT], fill=255) - for h in HOLES: d.polygon([m(p) for p in h], fill=0) - return img.resize((px,px), Image.LANCZOS) - -SIZES=[22,32,48]; ELEVS=[(90,"flat on"),(47,"47"),(16,"16"),(6,"6")] -pad,cell=8,58 -W=pad+len(SIZES)*len(ELEVS)*cell+pad; H=pad+2*cell+pad -sheet=Image.new("RGB",(W,H),(24,27,32)) -for r,fn in enumerate((flat, shade)): - for ci,(elev,_) in enumerate(ELEVS): - for si,px in enumerate(SIZES): - g=fn(px,elev) - tile=Image.new("RGB",(px,px),(24,27,32)) - if fn is flat: - tile.paste(Image.new("RGB",(px,px),(237,168,23)),(0,0),g) - else: - gg=g.convert("L") - tile=Image.merge("RGB",(gg.point(lambda v:min(255,int(v*1.00))), - gg.point(lambda v:int(v*0.71)), - gg.point(lambda v:int(v*0.16)))) - x=pad+(ci*len(SIZES)+si)*cell+(cell-px)//2 - y=pad+r*cell+(cell-px)//2 - sheet.paste(tile,(x,y)) -sheet.resize((W*2,H*2), Image.NEAREST).save(os.path.join(HERE,"relief-sheet.png")) - -# how much ink survives — the same measure used on the disc glyph -print(f"{'elev':>6} {'flat px@32':>11} {'relief px@32':>13}") -for elev,_ in ELEVS: - f32=flat(32,elev); s32=shade(32,elev) - fi=sum(1 for v in f32.getdata() if v>40) - si=sum(1 for v in s32.getdata() if v>40) - print(f"{elev:>6} {fi:>11} {si:>13}") -print("WROTE relief-sheet.png") diff --git a/docs/CAD/design/mate-connectors/relief_test.py b/docs/CAD/design/mate-connectors/relief_test.py deleted file mode 100644 index 3fb83b2a8e..0000000000 --- a/docs/CAD/design/mate-connectors/relief_test.py +++ /dev/null @@ -1,9 +0,0 @@ -# Export the real male's relief as a triangle mesh, so the grazing test uses the actual geometry. -import os, json -import Part -HERE = os.path.dirname(os.path.abspath(__file__)) -s = Part.Shape(); s.read(os.path.join(HERE, "bear.step")) -verts, facets = s.Solids[0].tessellate(0.25) -V = [[round(p.x,4), round(p.y,4), round(p.z,4)] for p in verts] -json.dump({"v": V, "f": facets}, open(os.path.join(HERE, "bear_mesh.json"), "w")) -print(f"verts {len(V)} facets {len(facets)}") diff --git a/docs/CAD/design/mate-connectors/render_key.py b/docs/CAD/design/mate-connectors/render_key.py deleted file mode 100644 index eb4bcdbd99..0000000000 --- a/docs/CAD/design/mate-connectors/render_key.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -"""Flat-shade the faceted ridge key from several camera directions. - -The point is not a pretty picture. It is one question: does a low-poly solid, flat-shaded, -let a human read its orientation from an arbitrary viewpoint -- and specifically, is the -view ALONG the ridge ambiguous between front and back, as the geometry suggests it must be -in silhouette? - -Flat shading (one normal per facet, no smoothing) is deliberate: it is what the concept -claims to rely on, and it is what a CAD viewport with hard normals actually produces. -""" -import numpy as np -from PIL import Image, ImageDraw - -# ---- the key, same numbers as faceted_ridge_key.scad -L, W, tf, H, pr, pf, hf = 12.0, 4.0, 0.45, 4.5, 0.22, 0.62, 0.35 -Wf, xr0, xr1, Hf = W * tf, -L / 2 + L * pr, -L / 2 + L * pf, H * hf - -V = np.array([(-L/2, -W, 0), (-L/2, W, 0), (L/2, Wf, 0), (L/2, -Wf, 0), - (xr0, 0, H), (xr1, 0, Hf)], dtype=float) -F = [[0, 1, 2, 3], [0, 4, 1], [0, 3, 5], [0, 5, 4], [1, 4, 5], [1, 5, 2], [3, 2, 5]] - -LIGHT = np.array([0.35, -0.5, 0.78]) # a headlight-ish key light -LIGHT /= np.linalg.norm(LIGHT) - - -def look_at(eye, target, up=(0, 0, 1)): - f = np.array(target, float) - np.array(eye, float) - f /= np.linalg.norm(f) - up = np.array(up, float) - if abs(np.dot(f, up)) > 0.999: - up = np.array([0, 1, 0], float) - r = np.cross(f, up); r /= np.linalg.norm(r) - u = np.cross(r, f) - return r, u, f - - -def render(eye, target, path, size=(620, 460), scale=26.0, label=""): - r, u, f = look_at(eye, target) - eye = np.array(eye, float) - cam = np.stack([r, u, f]) # world -> camera rows - P = (V - eye) @ cam.T # orthographic: x,y screen, z depth - - w, h = size - img = Image.new("RGB", size, (238, 240, 243)) - d = ImageDraw.Draw(img) - - def to_px(p): - return (w / 2 + p[0] * scale, h / 2 - p[1] * scale) - - faces = [] - for face in F: - pts = V[face] - n = np.cross(pts[1] - pts[0], pts[2] - pts[0]) - n /= np.linalg.norm(n) - centre = pts.mean(axis=0) - if np.dot(n, centre - eye) > 0: # back-face cull - continue - depth = P[face][:, 2].mean() - lam = max(0.0, float(np.dot(n, LIGHT))) - shade = 0.22 + 0.78 * lam # flat: ONE value for the whole facet - col = tuple(int(255 * shade * c) for c in (0.86, 0.72, 0.35)) - faces.append((depth, [to_px(P[i]) for i in face], col)) - - for _, poly, col in sorted(faces, key=lambda t: -t[0]): # painter's algorithm - d.polygon(poly, fill=col) - - if label: - d.rectangle([8, 8, 8 + 9 * len(label), 30], fill=(255, 255, 255)) - d.text((14, 14), label, fill=(20, 20, 20)) - img.save(path) - return path - - -if __name__ == "__main__": - t = (0, 0, H * 0.35) - views = [ - ((26, -22, 20), "iso: the reference view"), - ((30, 0, 6), "ALONG +X (from the FRONT, low end)"), - ((-30, 0, 6), "ALONG -X (from the BACK, tall end)"), - ((0, 0, 34), "ALONG +Z (straight down the mating axis)"), - ((2, -32, 5), "ALONG -Y (broadside, grazing)"), - ] - for i, (eye, lab) in enumerate(views): - print(render(eye, t, f"rk-{i}.png", label=lab)) diff --git a/docs/CAD/design/mate-connectors/render_stl.py b/docs/CAD/design/mate-connectors/render_stl.py deleted file mode 100644 index 16ad0e92a9..0000000000 --- a/docs/CAD/design/mate-connectors/render_stl.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -"""Flat-shade an ASCII/binary STL from several directions. - -Used to answer one question with a picture instead of an argument: does a RECESSED faceted -pocket read as an oriented feature, or does a concave feature collapse into a dark hole? -""" -import struct -import sys -import numpy as np -from PIL import Image, ImageDraw - -LIGHT = np.array([0.35, -0.5, 0.78]); LIGHT /= np.linalg.norm(LIGHT) - - -def load_stl(path): - data = open(path, "rb").read() - if data[:5] == b"solid" and b"facet" in data[:2000]: - tris, cur = [], [] - for line in data.decode("ascii", "ignore").splitlines(): - s = line.split() - if s and s[0] == "vertex": - cur.append([float(x) for x in s[1:4]]) - if len(cur) == 3: - tris.append(cur); cur = [] - return np.array(tris, dtype=float) - n = struct.unpack(" 0.999: up = np.array([0, 1.0, 0]) - r = np.cross(f, up); r /= np.linalg.norm(r) - u = np.cross(r, f) - cam = np.stack([r, u, f]) - - w, h = size - img = Image.new("RGB", size, (238, 240, 243)); d = ImageDraw.Draw(img) - faces = [] - for t in tris: - n = np.cross(t[1] - t[0], t[2] - t[0]) - ln = np.linalg.norm(n) - if ln < 1e-12: continue - n /= ln - c = t.mean(axis=0) - if np.dot(n, c - eye) > 0: continue # cull back faces - P = (t - eye) @ cam.T - lam = max(0.0, float(np.dot(n, LIGHT))) - shade = 0.20 + 0.80 * lam - col = tuple(int(255 * shade * ch) for ch in (0.86, 0.72, 0.35)) - poly = [(w / 2 + p[0] * scale, h / 2 - p[1] * scale) for p in P] - faces.append((P[:, 2].mean(), poly, col)) - for _, poly, col in sorted(faces, key=lambda x: -x[0]): - d.polygon(poly, fill=col) - if label: - d.rectangle([8, 8, 8 + 9 * len(label), 30], fill=(255, 255, 255)) - d.text((14, 14), label, fill=(20, 20, 20)) - img.save(path) - - -if __name__ == "__main__": - tris = load_stl(sys.argv[1]) - print("triangles:", len(tris)) - views = [((26, -22, 20), "iso"), ((0, 0, 34), "straight down +Z"), - ((4, -30, 9), "grazing"), ((-28, -10, 12), "from the tall end")] - for i, (eye, lab) in enumerate(views): - render(tris, eye, (0, 0, 0), f"fem-{i}.png", label=f"FEMALE POCKET — {lab}") - print(f"fem-{i}.png") diff --git a/docs/CAD/design/mate-connectors/rk-0.png b/docs/CAD/design/mate-connectors/rk-0.png deleted file mode 100644 index 1d7208238a..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-1.png b/docs/CAD/design/mate-connectors/rk-1.png deleted file mode 100644 index 282bd0a2fe..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-2.png b/docs/CAD/design/mate-connectors/rk-2.png deleted file mode 100644 index 75d83e1402..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-2.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-3.png b/docs/CAD/design/mate-connectors/rk-3.png deleted file mode 100644 index eccdf94807..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-3.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-4.png b/docs/CAD/design/mate-connectors/rk-4.png deleted file mode 100644 index 794fd4bd97..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-4.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/rk-back.png b/docs/CAD/design/mate-connectors/rk-back.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-front.png b/docs/CAD/design/mate-connectors/rk-front.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-iso.png b/docs/CAD/design/mate-connectors/rk-iso.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/CAD/design/mate-connectors/rk-sheet.png b/docs/CAD/design/mate-connectors/rk-sheet.png deleted file mode 100644 index e785a02839..0000000000 Binary files a/docs/CAD/design/mate-connectors/rk-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/simplify-sheet.png b/docs/CAD/design/mate-connectors/simplify-sheet.png deleted file mode 100644 index 9c05180c59..0000000000 Binary files a/docs/CAD/design/mate-connectors/simplify-sheet.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/simplify_study.py b/docs/CAD/design/mate-connectors/simplify_study.py deleted file mode 100644 index c0bbcf63ab..0000000000 --- a/docs/CAD/design/mate-connectors/simplify_study.py +++ /dev/null @@ -1,142 +0,0 @@ -"""Reduce the bear face to the fewest marks that still read at glyph size — wi3z. - -Geometry comes from bear_outline.json, which extract_outline.py pulled off the supplied male -B-rep's back plate: the outer wire IS the silhouette, the inner wires are the two eyes and the -muzzle opening. Nothing here is traced by eye. - -The glyph is drawn IN the connector's plane, so a grazing view foreshortens it along one axis by -sin(elevation) — exactly what collapsed the disc's roll quadrant to 3 pixels at 10 deg. Every -candidate is therefore rendered at three elevations as well as three pixel sizes. -""" -import json, math, os -from PIL import Image, ImageDraw - -HERE = os.path.dirname(os.path.abspath(__file__)) -D = json.load(open(os.path.join(HERE, "bear_outline.json"))) - -def norm(pts): - """Part frame (X right, Z down-negative) -> glyph frame (x right, y up), centred, unit height.""" - p = [(x, -z) for x, z in pts] - return p - -outer = norm(D["outer"]) -holes = [norm(h["pts"]) for h in D["holes"]] -# the two Ø9.8 wires are the eyes; the wide one is the muzzle -eyes = [h for h, meta in zip(holes, D["holes"]) if meta["d"] < 20] -muzzle = [h for h, meta in zip(holes, D["holes"]) if meta["d"] >= 20] - -ALL = outer + [p for h in holes for p in h] -xs = [p[0] for p in ALL]; ys = [p[1] for p in ALL] -CX, CY = (min(xs)+max(xs))/2, (min(ys)+max(ys))/2 -SPAN = max(max(xs)-min(xs), max(ys)-min(ys)) -def to_unit(pts): return [((x-CX)/SPAN, (y-CY)/SPAN) for x, y in pts] - -def rdp(pts, eps): - """Douglas-Peucker. Vertex count is the honest measure of 'how simplified'.""" - if len(pts) < 3: return pts - ax, ay = pts[0]; bx, by = pts[-1] - dx, dy = bx-ax, by-ay - n = math.hypot(dx, dy) - best, bi = -1.0, 0 - for i in range(1, len(pts)-1): - px, py = pts[i] - d = abs(dx*(ay-py) - (ax-px)*dy)/n if n > 1e-12 else math.hypot(px-ax, py-ay) - if d > best: best, bi = d, i - if best <= eps: - return [pts[0], pts[-1]] - return rdp(pts[:bi+1], eps)[:-1] + rdp(pts[bi:], eps) - -def simp_closed(pts, eps): - r = rdp(pts + [pts[0]], eps) - return r[:-1] - -def centroid(pts): - return (sum(p[0] for p in pts)/len(pts), sum(p[1] for p in pts)/len(pts)) - -U_OUT = to_unit(outer) -U_EYE = [to_unit(e) for e in eyes] -U_MUZ = [to_unit(m) for m in muzzle] - -def eye_dots(scale=1.0): - out = [] - for e in U_EYE: - cx, cy = centroid(e) - r = max(max(p[0] for p in e)-min(p[0] for p in e), - max(p[1] for p in e)-min(p[1] for p in e))/2*scale - out.append((cx, cy, r)) - return out - -def muzzle_tri(): - """The muzzle reduced to one filled triangle: its two lower corners and its apex.""" - m = U_MUZ[0] - lo = min(p[1] for p in m); hi = max(p[1] for p in m) - bottom = [p for p in m if p[1] < lo + 0.06*(hi-lo)] - apex = max(m, key=lambda p: p[1]) - return [min(bottom), max(bottom), apex] - -CANDIDATES = { - "C0 full": dict(out=U_OUT, eyes=eye_dots(), muz=U_MUZ[0]), - "C1 eps .004": dict(out=simp_closed(U_OUT, .004), eyes=eye_dots(), muz=simp_closed(U_MUZ[0], .004)), - "C2 eps .012": dict(out=simp_closed(U_OUT, .012), eyes=eye_dots(), muz=muzzle_tri()), - "C3 eps .030": dict(out=simp_closed(U_OUT, .030), eyes=eye_dots(1.15), muz=muzzle_tri()), - "C4 no eyes": dict(out=simp_closed(U_OUT, .012), eyes=[], muz=muzzle_tri()), -} - -def sym_report(pts, tol=0.02): - """Trivial symmetry group is the property doing the work. If a simplification restores a - mirror or a 180 deg rotation, that simplification is wrong.""" - def match(tf): - t = [tf(p) for p in pts] - hit = 0 - for q in t: - if min(math.hypot(q[0]-p[0], q[1]-p[1]) for p in pts) <= tol: hit += 1 - return hit, len(pts) - return { - "mirror-x": match(lambda p: (-p[0], p[1])), - "mirror-y": match(lambda p: ( p[0], -p[1])), - "rot-180": match(lambda p: (-p[0], -p[1])), - } - -def render(c, px, elev_deg, supersample=8): - S = px*supersample - img = Image.new("L", (S, S), 0) - d = ImageDraw.Draw(img) - k = math.sin(math.radians(elev_deg)) - def m(p): - return (S/2 + p[0]*S*0.92, S/2 - p[1]*S*0.92*k) - d.polygon([m(p) for p in c["out"]], fill=255) - if c["muz"]: d.polygon([m(p) for p in c["muz"]], fill=0) - for cx, cy, r in c["eyes"]: - a = m((cx-r, cy+r)); b = m((cx+r, cy-r)) - d.ellipse([a[0], a[1], b[0], b[1]], fill=0) - return img.resize((px, px), Image.LANCZOS) - -print(f"{'candidate':14} {'verts':>6} {'marks':>6} symmetry (matched/total, lower is better)") -print("-"*78) -for name, c in CANDIDATES.items(): - s = sym_report(c["out"]) - marks = 1 + (1 if c["muz"] else 0) + len(c["eyes"]) - sym = " ".join(f"{k} {v[0]}/{v[1]}" for k, v in s.items()) - print(f"{name:14} {len(c['out']):6} {marks:6} {sym}") - -SIZES = [22, 32, 48] -ELEVS = [(90, "flat on"), (47, "47 deg"), (16, "16 deg"), (6, "6 deg")] -pad, cell = 8, 56 -W = pad + len(SIZES)*len(ELEVS)*cell + pad -H = pad + len(CANDIDATES)*cell + pad -sheet = Image.new("RGB", (W, H), (24, 27, 32)) -for r, (name, c) in enumerate(CANDIDATES.items()): - for ci, (elev, _) in enumerate(ELEVS): - for si, px in enumerate(SIZES): - g = render(c, px, elev) - tile = Image.new("RGB", (px, px), (24, 27, 32)) - gold = Image.new("RGB", (px, px), (237, 168, 23)) - tile.paste(gold, (0, 0), g) - x = pad + (ci*len(SIZES)+si)*cell + (cell-px)//2 - y = pad + r*cell + (cell-px)//2 - sheet.paste(tile, (x, y)) -sheet = sheet.resize((W*2, H*2), Image.NEAREST) -sheet.save(os.path.join(HERE, "simplify-sheet.png")) -print("\ncolumns: " + " | ".join(f"{e[1]} @ 22/32/48px" for e in ELEVS)) -print("rows: " + ", ".join(CANDIDATES)) -print("WROTE simplify-sheet.png") diff --git a/docs/CAD/design/mate-connectors/size-test.png b/docs/CAD/design/mate-connectors/size-test.png deleted file mode 100644 index 941f76ffb8..0000000000 Binary files a/docs/CAD/design/mate-connectors/size-test.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-down+Z.png b/docs/CAD/design/mate-connectors/sz-22-down+Z.png deleted file mode 100644 index 85cbf9ba4e..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-grazing.png b/docs/CAD/design/mate-connectors/sz-22-grazing.png deleted file mode 100644 index 047f2c6e06..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-22-iso.png b/docs/CAD/design/mate-connectors/sz-22-iso.png deleted file mode 100644 index 55b8a13eed..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-22-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-down+Z.png b/docs/CAD/design/mate-connectors/sz-32-down+Z.png deleted file mode 100644 index 683fc3d0aa..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-grazing.png b/docs/CAD/design/mate-connectors/sz-32-grazing.png deleted file mode 100644 index 92e17ca09a..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-32-iso.png b/docs/CAD/design/mate-connectors/sz-32-iso.png deleted file mode 100644 index 1fe0ccb091..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-32-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-down+Z.png b/docs/CAD/design/mate-connectors/sz-48-down+Z.png deleted file mode 100644 index ec451714ff..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-down+Z.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-grazing.png b/docs/CAD/design/mate-connectors/sz-48-grazing.png deleted file mode 100644 index 524c8e5343..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-grazing.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/sz-48-iso.png b/docs/CAD/design/mate-connectors/sz-48-iso.png deleted file mode 100644 index e0ed208b64..0000000000 Binary files a/docs/CAD/design/mate-connectors/sz-48-iso.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+0.1-0.png b/docs/CAD/design/mate-connectors/t-+0.1-0.png deleted file mode 100644 index b0c09ef253..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+0.1-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+0.1-1.png b/docs/CAD/design/mate-connectors/t-+0.1-1.png deleted file mode 100644 index 782cd16c0d..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+0.1-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+1.6-0.png b/docs/CAD/design/mate-connectors/t-+1.6-0.png deleted file mode 100644 index f3b37f6697..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+1.6-0.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/t-+1.6-1.png b/docs/CAD/design/mate-connectors/t-+1.6-1.png deleted file mode 100644 index 731e092769..0000000000 Binary files a/docs/CAD/design/mate-connectors/t-+1.6-1.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/trim-cmp.png b/docs/CAD/design/mate-connectors/trim-cmp.png deleted file mode 100644 index 8dcc0c973f..0000000000 Binary files a/docs/CAD/design/mate-connectors/trim-cmp.png and /dev/null differ diff --git a/docs/CAD/design/mate-connectors/trim_female.py b/docs/CAD/design/mate-connectors/trim_female.py deleted file mode 100644 index 2753e4a3a8..0000000000 --- a/docs/CAD/design/mate-connectors/trim_female.py +++ /dev/null @@ -1,74 +0,0 @@ -# Trim the boxy frame off the female so its outer shape is the bear face itself. -# -# Method: take the male's flat back face (the plane Y=0 -- that face IS the bear silhouette), -# offset its OUTER wire outward in 2D, extrude the result along the insertion axis, and keep only -# the part of the female inside it. Everything outside is the block frame and goes away. -# -# NOTE ON THE NUMBER. The pocket's side walls stand at +0.20 mm from the male outline, because that -# is the clearance. A trim boundary at +0.10 mm therefore falls INSIDE them by 0.10 mm and removes -# the side wall entirely rather than leaving a thin one. The script runs the requested value and -# then measures what is actually left, so the outcome is a number rather than an opinion; it also -# emits a second variant at an offset that leaves a printable wall, for comparison. -# -# Run: /snap/bin/freecad.cmd trim_female.py - -import os, sys -import FreeCAD as App -import Part -from FreeCAD import Vector - -HERE = os.path.dirname(os.path.abspath(__file__)) -MALE = os.path.join(HERE, "bear.step") -FEMALE = os.path.join(HERE, "BearConnector_Female.step") - -REQUESTED = 0.10 # as asked -CLEARANCE = 0.20 # what the pocket was built with -SAFE_WALL = 1.60 # a wall that survives an FDM nozzle: clearance + ~1.4 mm - -male = Part.Shape(); male.read(MALE); male = male.Solids[0] -fem = Part.Shape(); fem.read(FEMALE); fem = fem.Solids[0] -print(f"female in : {fem.Volume/1000:.2f} cm3, {len(fem.Faces)} faces") - -# --- the bear silhouette: the male's flat back face at Y = 0 -back = None -for f in male.Faces: - n = f.normalAt(0, 0) - if abs(f.CenterOfMass.y) < 1e-6 and abs(abs(n.y) - 1.0) < 1e-6: - if back is None or f.Area > back.Area: - back = f -if back is None: - print("FAIL: could not find the flat back face at Y=0"); sys.exit(1) -print(f"silhouette: back face area {back.Area:.1f} mm2, {len(back.Wires)} wires " - f"(outer + {len(back.Wires)-1} holes: eyes and mouth)") - -fb = fem.BoundBox -y0, y1 = fb.YMin - 5.0, fb.YMax + 5.0 - -def trimmed(offset): - """keep only the part of the female inside the silhouette grown by `offset`""" - wire = back.OuterWire - grown = wire.makeOffset2D(offset, join=2, fill=False, openResult=False, intersection=True) - face = Part.Face(Part.Wire(grown.Edges)) - prism = face.extrude(Vector(0, y1 - y0, 0)) - prism.translate(Vector(0, y0 - face.CenterOfMass.y, 0)) - return fem.common(prism) - -for tag, off, out in (("requested", REQUESTED, "BearConnector_Female_Trimmed.step"), - ("safe wall", SAFE_WALL, "BearConnector_Female_Trimmed_wall.step")): - r = trimmed(off) - if not r.Solids: - print(f"\n{tag} (+{off:.2f} mm): NOTHING LEFT"); continue - wall = off - CLEARANCE - # is there any material left at the level of the pocket's side wall? - sec = r.section(Part.makePlane(400, 400, Vector(-200, 1.5, -200), Vector(0, 1, 0))) - perim = sum(e.Length for e in sec.Edges) - print(f"\n{tag} (+{off:.2f} mm) wall = {wall:+.2f} mm") - print(f" volume {r.Volume/1000:.2f} cm3, {len(r.Solids)} solid(s), {len(r.Faces)} faces") - print(f" section through the pocket wall at Y=1.5: {perim:.1f} mm of edge") - if wall <= 0: - print(f" -> the trim cuts {abs(wall):.2f} mm INSIDE the pocket wall: no side wall remains") - doc = App.newDocument(tag.replace(" ", "_")) - o = doc.addObject("Part::Feature", "Female") - o.Shape = r; doc.recompute() - Part.export([o], os.path.join(HERE, out)) - print(f" wrote {out}") diff --git a/docs/CAD/design/mate-connectors/verify_trimmed.py b/docs/CAD/design/mate-connectors/verify_trimmed.py deleted file mode 100644 index 81f6f3fea1..0000000000 --- a/docs/CAD/design/mate-connectors/verify_trimmed.py +++ /dev/null @@ -1,25 +0,0 @@ -# Check both trimmed females still fit the male, and export STLs for a visual comparison. -# Run: /snap/bin/freecad.cmd verify_trimmed.py -import os -import Mesh, Part - -HERE = os.path.dirname(os.path.abspath(__file__)) -male = Part.Shape(); male.read(os.path.join(HERE, "bear.step")); male = male.Solids[0] - -for name in ("BearConnector_Female_Trimmed", "BearConnector_Female_Trimmed_wall"): - p = os.path.join(HERE, name + ".step") - s = Part.Shape(); s.read(p); s = s.Solids[0] - d = male.distToShape(s)[0] - c = male.common(s) - cv = c.Volume if c.Solids else 0.0 - bb = s.BoundBox - print(f"{name}") - print(f" {bb.XLength:.2f} x {bb.YLength:.2f} x {bb.ZLength:.2f} mm, {s.Volume/1000:.2f} cm3, " - f"{len(s.Faces)} faces, valid={s.isValid()}") - print(f" gap to male {d:.4f} mm, interference {cv:.6f} mm3") - m = Mesh.Mesh(); m.addFacets([tuple(t) for t in s.tessellate(0.12)[1]] and - [(s.tessellate(0.12)[0][a], s.tessellate(0.12)[0][b], - s.tessellate(0.12)[0][c2]) - for a, b, c2 in s.tessellate(0.12)[1]]) - m.write(os.path.join(HERE, name + ".stl")) - print(f" wrote {name}.stl ({m.CountFacets} facets)") diff --git a/docs/CAD/design_tab.md b/docs/CAD/design_tab.md deleted file mode 100644 index 1be0a2ea33..0000000000 --- a/docs/CAD/design_tab.md +++ /dev/null @@ -1,333 +0,0 @@ -# The Design tab - -Object-driven parametric CAD inside the slicer. Point at geometry; the geometry offers the -verbs that apply to it. Selection comes first and the tool consumes it. Draw a sketch, -constrain it, turn it into a solid, refine it, and send it straight to Prepare — without -leaving for another application and coming back through an STL. - -The model is a **recipe**, not a mesh. Every action becomes a feature in a tree that is -replayed from the start whenever anything changes, so editing a dimension you set twenty -steps ago rebuilds everything downstream. The geometry kernel is OCCT, which the slicer -already ships for STEP import. - ---- - -## Getting started - -1. Open the **Design** tab. -2. Click a face or a reference plane in the viewport, then press `Shift+S` (Sketch). The offer - opens with the sketch tools on it. -3. Draw a closed profile, then press **✓ Confirm** in the floating action bar. -4. With the sketch selected, press `Shift+E` (Extrude). -5. Press **Commit to Plate** to hand the solid to Prepare. - -The status line under the toolbar is the thing to watch: it says what the current tool is -waiting for. When no plane is picked it reads *"Click a face or a reference plane in the -viewport, then a sketch tool"*; once one is picked it reads *"Sketching on — pick a -tool"*. It is also where a refusal explains itself. - ---- - -## Selecting - -- One left-click selects what is under the cursor. There is no click-cycling through - face → edge → body. -- A click near a corner takes the corner, not the face behind it. -- Left-drag sweeps a rubber band, and a rubber band takes the whole body. -- An open sketch line can be clicked, even where it bounds a region. -- Double-click a sketch stroke to edit it — the gesture belongs on the geometry. -- Editing a dimension's value **updates** that dimension instead of adding a second one next - to it. -- The floating chrome that belongs to a sketch leaves with the sketch when it ends. -- Sketching happens on the face you clicked, first click. -- A sketch whose entities form no wire **fails** instead of extruding a default box. A - subtraction that removes nothing is reported as an error instead of a silent success. - ---- - -## The offer - -Right-click on the geometry, released without moving the mouse (an 8 px budget — a -right-drag that orbits the camera does not open it). Left-click still only selects, so -pointing at things stays quiet. - -The offer also opens by itself the moment you press Sketch on a face or plane, showing the -sketch tools — the app hands you the tools directly. - -**Eight families, always in this fixed order:** Create, Add material, Remove, Dress-up, -Repeat, Transform, Reference, Modify. - -- A family with at least one applicable verb shows it. Several applicable verbs collapse - into a submenu under the family name. -- A family with nothing applicable is **shown greyed in place, with the reason** — e.g. - *"Create — Click a face or a reference plane in the viewport, then a sketch tool"*. It is - not hidden. A control that cannot be used still says what it is and what you would have to - do first. -- Inside a sketch the offer shows the sketch verbs; outside it shows the feature verbs. - -**Document-level actions never enter the offer**, because they act on the document and not -on a selection: Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, -Redo, Variables, Section view, Origin planes, World axes. They live in the toolbar. - ---- - -## Keyboard - -Single letters drive sketch tools **while a sketch is open**; Shift+letter drives feature -tools and single letters drive view toggles **when no sketch is open**. The two maps are -selected by the mode, not by whether a sketch session is running. - -### Sketch (while a sketch is open) - -| Key | Tool | -|---|---| -| `L` | Line — click start, then end | -| `R` | Rectangle — click two opposite corners | -| `C` | Circle — click centre, then radius | -| `A` | Arc — click start, end, then a point | -| `S` | Slot — two centreline ends, then width | -| `E` | Ellipse — centre, major end, minor point | -| `B` | Spline — click control points | -| `P` | Point — click to place | -| `G` | Polygon — click centre, then a vertex | -| `D` | Dimension — click 2 points or an entity | -| `T` | Trim — click a segment to trim it | -| `X` | Extend — click a line/arc to extend it | -| `O` | Offset — pick an entity, drag the distance | -| `M` | Mirror — pick axis, then entities | -| `F` | Fillet — pick two lines, set the radius | -| `H` | Chamfer — pick two lines, set the distance | -| `K` | Constrain — finish the live sketch and enter constrain | -| `Q` | Construction toggle — draw the next entity as construction geometry | -| `Del` | Delete the selected sketch entity | -| `Esc` | Cancel the live tool | - -### Feature (when no sketch is open) - -| Key | Tool | -|---|---| -| `Shift+S` | Sketch | -| `Shift+E` | Extrude — extrude a profile, or push/pull a picked face | -| `Shift+R` | Revolve | -| `Shift+W` | Sweep | -| `Shift+L` | Loft | -| `Shift+N` | Pattern | -| `Shift+G` | Surface Extrude | -| `Shift+J` | Surface Revolve | -| `Shift+O` | Surface Loft | -| `Shift+Q` | Surface Fill | -| `Shift+U` | Surface Offset | -| `Shift+V` | Thicken Surface | -| `Shift+P` | Plane | -| `Shift+A` | Axis | -| `Shift+C` | Coord Sys | -| `Shift+Y` | Transform | -| `Shift+Z` | Mirror | -| `Shift+B` | Boolean | -| `Shift+X` | Cut | -| `Shift+F` | Fillet / Chamfer | -| `Shift+D` | Draft | -| `Shift+K` | Shell | -| `Shift+H` | Hole | -| `Shift+T` | Thread | -| `Shift+I` | Import STEP | -| `Shift+M` | Import mesh | - -### View toggles (single letters, when no sketch is open) - -| Key | Action | -|---|---| -| `Home` | Axonometric view, fitted to the model | -| `P` | Origin planes on/off | -| `A` | World axes on/off | -| `X` | Section view on/off | - -While the section is on: `PageUp` / `PageDown` move the cut plane, `F` flips which half is -kept. With no section on, `F` is Place on Face — lay the picked face flat on the bed. - ---- - -## Sketching - -A sketch is a closed (or open) 2D profile on a plane or on a flat face of an existing body. -Press `Shift+S`, click the face or plane you want to sketch on, and draw. The toolbar and -the offer both carry the sketch tools. - -**Entities:** line, polyline, rectangle (corner / centre / oblique / rounded), circle -(centre-radius / 2-point / 3-point), arc (centre-point / 3-point / tangent), ellipse and -elliptical arc, polygon (inscribed / circumscribed), slot (straight / arc), spline, point, -and text. - -**Editing:** move, rotate, scale, trim, extend, offset, mirror, and linear or polar arrays. - -**Constraints:** coincident, horizontal, vertical, parallel, perpendicular, tangent, equal, -concentric, midpoint, symmetric, fix, plus dimensional radius, diameter, distance and angle. -The solver reports the remaining degrees of freedom and tells you when a sketch is fully -constrained — or when a constraint conflicts with one already there. - -Sketches stay editable. Selecting one in the feature tree reopens it with its dimensions -live. - ---- - -## Building solids - -Grouped in the toolbar by what they do, one concept per drawer. - -### Add material -| Tool | Shortcut | What it does | -|---|---|---| -| Extrude | `Shift+E` | Extrude a profile, or push/pull a face already on a body | -| Revolve | `Shift+R` | Revolve a profile about an axis | -| Sweep | `Shift+W` | Sweep a profile along a path — including a helix, for springs and augers | -| Loft | `Shift+L` | Skin between two or more profiles | -| Thicken | — | Offset a solid face into a thin plate as a new body | -| Rib | — | Grow a stiffening wall from an open sketch line, fused to a body | - -Extrude offers blind, symmetric, two-sided, through-all and up-to-face end conditions, plus -a draft angle on the side wall, and can add, subtract, intersect or start a new body. - -### Surface -Sheet bodies — surfaces with no thickness — for shapes that are easier to build as skins and -solidify afterwards. - -| Tool | Shortcut | -|---|---| -| Surface Extrude | `Shift+G` | -| Surface Revolve | `Shift+J` | -| Surface Loft | `Shift+O` | -| Surface Fill | `Shift+Q` | -| Surface Offset | `Shift+U` | -| Thicken Surface | `Shift+V` | - -Thicken Surface is how a sheet becomes a printable solid. - -### Dress-up -| Tool | Shortcut | -|---|---| -| Fillet / Chamfer | `Shift+F` | -| Draft (taper a face) | `Shift+D` | -| Shell | `Shift+K` | -| Delete Face | — | - -Delete Face removes faces and heals the solid — useful for stripping a feature off an -imported part. - -### Holes -**Hole** (`Shift+H`) drills simple, counterbored or countersunk holes, with an ISO/ANSI -standards table so you can ask for an M6 clearance hole instead of computing a diameter. -**Thread** (`Shift+T`) cuts a real helical thread into a bore or onto a shaft. - -### Placement -Operations that move a body without changing its shape: **Transform** (`Shift+Y`), -**Mirror** (`Shift+Z`), and **Mate** for assemblies. - -### Combining -**Boolean** (`Shift+B`) unions, subtracts or intersects two bodies. **Cut** (`Shift+X`) -splits a body with a plane. **Pattern** (`Shift+N`) repeats a body linearly, in a circle, or -along a curve. - ---- - -## Reference geometry - -Datum features carry no material; they exist to give later features something to attach to. - -- **Plane** (`Shift+P`) — offset, tilted, midplane, tangent, through two edges, or coincident -- **Axis** (`Shift+A`) — two points, a face normal, a cylinder centreline, the intersection of - two planes, or along an edge -- **Coord Sys** (`Shift+C`) — a full frame, from a world point or from a face plus a - direction edge -- **Helix** — a helical curve to sweep along -- **Project** — project a body's edges onto a plane as sketch geometry - -On the Coord Sys tool, picking a direction **edge** is worth the extra click: without one the -frame takes its X from the face's first edge, which is deterministic but not necessarily the -direction you meant. - ---- - -## Assemblies - -**Mate** aligns two coordinate systems and moves one body onto the other. Five kinds: - -| Kind | Leaves free | -|---|---| -| Fastened | nothing — 6 DOF locked | -| Planar | sliding in the plane | -| Revolute | rotation about the axis | -| Slider | sliding along the axis | -| Cylindrical | rotation *and* sliding | - -**Check interference** reports every overlapping pair of solids with the overlapping volume, -so a clash is a number rather than an impression. Bodies that merely touch enclose no volume -and are not reported. - ---- - -## Variables and expressions - -Define named variables and drive dimensions from them. Any numeric field accepts an -expression — `width/2`, `wall*3` — and everything re-evaluates on recompute. Change one -variable and the whole model follows. - ---- - -## Import and export - -**Import STEP** brings in a real B-rep solid, not a mesh: its faces and edges can be filleted, -shelled and cut like anything modelled here. - -**Import mesh** (STL/OBJ) converts triangles to a B-rep body and tells you honestly what it -got — whether the result is a closed solid or an open shell, with the boundary and -non-manifold edge counts. A large mesh becomes a large number of faces, which is slow to -edit; the importer warns before you commit to it. - -**Export STEP** writes the model out for another CAD tool. - -**Commit to Plate** sends the solid to Prepare for slicing. The whole feature recipe is saved -inside the 3MF, so reopening the project restores the editable model rather than a frozen -mesh. - ---- - -## View controls - -**Section view** (`X`) hides half the model so you can see inside — `PageUp`/`PageDown` move -the plane, `F` flips which half is kept. **Place on Face** (`F`, when section is off) lays a -picked face flat on the bed. Origin planes (`P`) and world axes (`A`) can be toggled on while -you orient yourself. - ---- - -## Known limitations - -Being straight about the edges, so nobody discovers them the hard way: - -- **Rib** needs a sketch containing an explicit open line. A parametric rectangle sketch - carries no individual entities, so Rib cannot use one. -- **Surface Loft** and **Surface Fill** have kernel tests but have not been exercised by hand. -- Card wiring for 9 of the 16 late-wired tools has never been click-tested. -- Mate resolves by composing transforms directly. There is no 3D assembly solver, so mates - are applied in order rather than solved simultaneously, and mate limits are not implemented. -- Move-face and replace-face are not implemented — OCCT offers no clean primitive for them. -- There is no automated GUI test in CI. Every behaviour above is traced to code and to a - hand pass, not to a synthetic click. - ---- - -## Where the code lives - -| Path | Role | -|---|---| -| `src/libslic3r/CAD/CadDocument.*` | the feature recipe and its replay | -| `src/libslic3r/CAD/GeometryEngine.*` | OCCT wrapper — faces, edges, booleans, healing | -| `src/libslic3r/CAD/SketchEngine.*` | profile → wire → solid | -| `src/libslic3r/CAD/SketchSolver.*` | constraint solving, over the vendored solver | -| `src/libslic3r/slvs/` | vendored 2D constraint solver (GPLv3) | -| `src/slic3r/GUI/CAD/DesignPanel.*` | the tab: toolbar, cards, feature tree | -| `src/slic3r/GUI/CAD/DesignCanvas.*` | viewport integration | -| `src/slic3r/GUI/CAD/DesignSketchTool.*` | in-canvas sketching | - -Build with `-DSLIC3R_CAD=ON` (the default). With it OFF the tab is not compiled and the deps -prefix matches upstream exactly — see [cad_dependency_weight.md](cad_dependency_weight.md). diff --git a/docs/CAD/design_tab_pr_description.md b/docs/CAD/design_tab_pr_description.md deleted file mode 100644 index a6d67f0e7c..0000000000 --- a/docs/CAD/design_tab_pr_description.md +++ /dev/null @@ -1,73 +0,0 @@ -# Design (CAD) tab — upstream pull request - -## What this adds - -A sketch-first parametric CAD tab inside the slicer. The workflow is direct: -sketch → constrain → solid features → commit to plate. The whole feature recipe is -persisted inside the 3MF, so reopening restores an editable model rather than a frozen mesh. - -- Kernel: OCCT, which upstream already links for STEP import — see - [cad_dependency_weight.md](docs/cad_dependency_weight.md) -- Constraint solver: vendored SolveSpace `libslvs` subset -- Interaction model: object-driven — point at geometry, the geometry offers the verbs that - apply to it; see [cad_ux_guidelines.md](docs/cad_ux_guidelines.md) -- Full user-facing documentation: [design_tab.md](docs/design_tab.md) - -## Why it belongs in the slicer - -Every round trip through an external CAD tool costs a file export, a re-import, and the -design intent that both steps discard. A part modified after slicing should return to its -feature history, not to a mesh. Keeping the CAD model inside the slicer preserves that -loop — the nozzle diameter, the build volume and the material are known at design time. - -For the integration case in full: [design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md). - -## How it is built - -The `SLIC3R_CAD` CMake flag (default ON) gates the entire tab. With it OFF the tab is not -compiled and the deps prefix matches upstream exactly — the dependency diff is one line in -OCCT's CMake: `BUILD_MODULE_ModelingAlgorithms=OFF → ON`. - -Measured cost table: [cad_dependency_weight.md](docs/cad_dependency_weight.md). - -## Diff shape - - - -Against merge-base `d6cb667b894f`: - - 306 files changed, 83032 insertions(+), 777 deletions(-) - -350 commits, of which 284 are new files and 37 modify upstream files. 99.3 % of the diff -is new code. The negotiable surface is the 37 modified files. - -## Tests - -205 `TEST_CASE` blocks across 6 new test source files. This counts assertions written, not -assertions passed — a run needs a build. - -`scripts/CAD/run-kernel-tests.sh` is the headless verification contract: it builds only -`libslic3r_tests` (not the GUI app), needs no display, and exit 0 means the CAD suite -passed. It now runs with **no exclusions** — both cases that used to be quarantined (the -circle-line tangency solver abort and the internal-thread reference) are fixed. - -## Licensing - -The vendored solver in `src/libslic3r/slvs/` is **GPL-3.0** (see `src/libslic3r/slvs/LICENSE`), -not LGPL. The combined work is distributable under AGPL-3.0. See the Licensing section of -[design_tab_upstream_portability.md](docs/design_tab_upstream_portability.md) for the -AGPLv3/GPLv3 compatibility argument; this point should be confirmed with upstream explicitly. - -## Not verified - -- Card wiring for 9 of the 16 late-wired tools was never click-tested. -- There is no automated GUI test in CI. A green kernel run says nothing about the GUI — - synthetic clicks never drift, so the test suite and the viewport are two separate realities. -- The click-test defect rate has **not converged**: a second pass found no new defects, but - four further days of work found five more. The earlier pass is not evidence of stability. - -## Reviewer's map - -See the [Where the code lives](docs/design_tab.md#where-the-code-lives) table in the user -doc for the file-to-role mapping, and [docs/ux/tool_atlas.json](docs/ux/tool_atlas.json) as -the generated-from source of `src/slic3r/GUI/CAD/DesignOffer.hpp`. diff --git a/docs/CAD/design_tab_upstream_portability.md b/docs/CAD/design_tab_upstream_portability.md deleted file mode 100644 index a7e9cd84ed..0000000000 --- a/docs/CAD/design_tab_upstream_portability.md +++ /dev/null @@ -1,162 +0,0 @@ -# Design (CAD) tab — upstream integration brief - -**Question:** can the Design tab (sketch-first parametric CAD: sketch → constrain → -extrude/revolve/fillet/hole/thread/shell, multi-body, undo, 3MF persistence) land in -mainline OrcaSlicer? - -**Answer: yes, and the ask is far smaller than previously believed.** OCCT is *already* -an OrcaSlicer dependency. We are not asking upstream to adopt a new library; we are -asking it to widen one it already builds, at a measured cost of **3.77 MiB on Windows**. - -> ### Corrections to the 2026-06-21 assessment -> That revision was written before the persistence work landed and got two load-bearing -> facts wrong. Both are corrected here from direct measurement of the branch: -> -> 1. **"The real blocker: OCCT … a dependency mainline OrcaSlicer has never carried."** -> **False.** `deps/OCCT/` exists at the merge-base and upstream links it from -> `Format/STEP.cpp`, `Format/svg.cpp`, and `Shape/TextShape.cpp`. Our entire -> dependency diff is **one line**: `BUILD_MODULE_ModelingAlgorithms=OFF → ON`. -> 2. **"vendored SolveSpace solver … LGPL."** **False.** `src/libslic3r/slvs/LICENSE` is -> **GPL-3.0**, not LGPL. This is fine (see Licensing) but must not be misstated. -> -> It also claimed "no changes to Model" — no longer true; 3MF recipe persistence adds one -> `std::string` to `Model`. - -## Measured shape of the change - -Against merge-base `449a4cf9fc` (34 commits ahead): - -| | files | lines | -|---|---:|---:| -| **New files** | 138 | +61,720 | -| **Modified upstream files** | 23 | +457 / −75 | -| **Deleted upstream files** | 0 | — | - -The 62 kLOC headline is inflated by localization. The feature itself: - -| area | LOC | files | -|---|---:|---:| -| kernel (`src/libslic3r/`) | 15,828 | 37 | -| GUI (`src/slic3r/`) | 19,544 | 14 | -| tests (Catch2) | 2,567 | 6 | -| i18n (unrelated; strip from the CAD PR) | 23,438 | 77 | - -**99.3 % of the diff is new files.** The negotiable surface is 457 added lines across 23 -files, and nothing upstream is deleted. The largest single hook is `GLCanvas3D.cpp` -(+110/−2): an `m_design_sketch_tool` member plus render/mouse/key hooks, **every one -already null-guarded** — which is why the compile-time gate below is cheap. - -No changes to the slicing pipeline (Print/PrintObject/Layer/GCode), Tab, or the -printer-profile/config system. - -## The dependency ask, precisely - -Not "adopt OCCT" — **widen the existing OCCT build**: - -```diff -- -DBUILD_MODULE_ModelingAlgorithms=OFF -+ -DBUILD_MODULE_ModelingAlgorithms=ON -``` - -Cost, measured from the shipped Windows artifact (42 OCCT DLLs, 45.43 MiB total): - -| toolkit | size | note | -|---|---:|---| -| `TKFillet.dll` | 2.02 MiB | only exists with the flag ON | -| `TKOffset.dll` | 1.75 MiB | only exists with the flag ON | -| **delta** | **3.77 MiB** | Windows only (OCCT is Shared on Win, Static elsewhere) | - -`TKBool` is *not* part of the delta — upstream's `DataExchange` already pulls it in -transitively. On macOS/Linux OCCT links statically, so the cost is only the code actually -referenced, not a 3.77 MiB floor. - -**Unmeasured, and we should measure before the call:** clean-deps build-time delta with -the flag ON vs OFF, and the resulting CI runner-minute cost. Do not guess these at him. - -## Licensing - -- Vendored solver `src/libslic3r/slvs/` — **GPL-3.0**, 9,339 LOC, © Jonathan Westhues, - a self-contained subset of SolveSpace (`libslvs`). No external dependencies. -- OrcaSlicer — **AGPL-3.0** (`LICENSE.txt`). - -GPLv3 §13 expressly permits combining a GPLv3 work with an AGPLv3 work; AGPLv3 §13 grants -the converse. The combined work is distributable under AGPL-3.0 with the solver's GPLv3 -terms preserved. This is a favourable direction (GPLv3 → into an AGPLv3 project), but it -is a point to **confirm explicitly with upstream**, not to assert unilaterally. - -Open question for SoftFever: keep the solver **vendored** (current: pinned, no submodule, -no external build) or move it to `deps/` as a fetched external? Vendoring costs us -upstream-sync burden; `deps/` costs build complexity. - -## The one irreversible decision: the 3MF format - -Persistence adds an **optional** archive entry and one field: - -```cpp -// Model.hpp -std::string cad_recipe; // empty for non-CAD projects -``` - -``` -Metadata/orca_cad.bin // written only when cad_recipe is non-empty -``` - -Readers that do not know the entry ignore it; writers skip it entirely when empty. So -existing projects are bit-identical and old readers are unaffected. Good. - -**But the moment upstream ships this, it owns forward-compatibility forever.** Three -things should be settled *before* the first release, because none can be changed after: - -1. **Name.** Renamed to `Metadata/orca_cad.bin`. -2. **Encoding.** The recipe is an opaque **cereal `PortableBinaryArchive`** blob whose - layout is the field order of `CadFeature::serialize`. Portable across endianness and - word size — *not* across a field reorder. Append-only is currently a convention held by - discipline, not by any check. -3. **Embedded BRep.** `Import` features embed OCCT's ASCII BRep for the imported solid, - which couples saved project files to an OCCT BRep revision. Alternative: re-import from - the source STEP and store only a reference. Worth deciding deliberately. - -**Concrete gap we should close before the call.** `test_caddocument.cpp` covers the -in-memory round-trip and correctly refuses a version-999 blob — but there is **no -checked-in v1 fixture on disk**. A reordered field in `CadFeature::serialize` would pass -the entire suite while silently breaking every previously-saved project. Ship a golden -`.bin` fixture generated today plus a test that loads it; that is the only thing that will -hold the format still once real users have files. - -## Proposed PR decomposition - -35 kLOC in one PR is not reviewable. Behind the flag, slices 1–4 are behaviour-neutral for -existing users: - -1. **Build gate + OCCT flag + Windows packaging guard.** `-DSLIC3R_CAD=ON/OFF`, default - **OFF**. Flips `ModelingAlgorithms=ON`. Includes the guard that asserts every linked - OCCT toolkit has a shipped DLL (already on both forks: `546cef5f42`). ← *this is what - makes SoftFever's "parallel build" a one-line CI matrix entry.* -2. **Vendored `slvs` solver** + its Catch2 tests. No GUI, no OCCT. -3. **CAD kernel** (`CadDocument`, `SketchEngine`, `GeometryEngine`, `Sketch*`) + kernel - tests. Headless, no GUI. -4. **3MF recipe persistence** + golden-fixture regression test. -5. **GUI Design tab** (`DesignPanel`, `DesignCanvas`, `DesignSketchTool`, `GLGizmoSketch`) - + the 23 upstream hooks. - -## Agenda for the call - -Questions only SoftFever can answer: - -- Does OrcaSlicer *want* to be a CAD-integrated slicer? (Strategic; everything else is mechanical.) -- Default of `SLIC3R_CAD` at merge time, and when it flips ON. -- Vendored solver vs `deps/` external; and confirmation of the GPLv3/AGPLv3 combination. -- Project-file format: neutral name, encoding, embedded-BRep policy, and who owns v1 forward-compat. -- Undo/redo: the Design tab has its own stack; integrate with Orca's snapshot system or keep separate? -- Does he want the i18n work (Romanian, +23 kLOC) as a wholly separate PR? (Yes, almost certainly.) - -## Verdict - -Portability **high**. The prior "does upstream want OCCT" framing was wrong — OCCT is -already there. What remains is a 3.77 MiB dependency widening, a compile-time gate that -the existing null-guards make cheap, and one file-format decision that must be made before -the first release rather than after. - ---- -*Revised 2026-07-10 from direct measurement of `cad-mainline` @ `546cef5f42` vs upstream -merge-base `449a4cf9fc`. Supersedes the 2026-06-21 read-only assessment.* diff --git a/docs/CAD/ux/interaction-model.md b/docs/CAD/ux/interaction-model.md deleted file mode 100644 index 2041978ea0..0000000000 --- a/docs/CAD/ux/interaction-model.md +++ /dev/null @@ -1,144 +0,0 @@ -# Design tab — interaction model - -The contract for Esc, the right mouse button, and the states between them. Code that changes any -of the three changes this file in the same commit. - -## 1. The state machine - -`src/slic3r/GUI/CAD/DesignInteraction.hpp` — a four-level LIFO stack. The enum value *is* the -depth, so "which level does this press belong to" is a comparison rather than a chain of -special cases spread over three files. - -```cpp -enum class CadLevel : int { - Idle = 0, // nothing transient is up: Esc clears the selection - Tool = 1, // a feature card / armed sketch tool / constrain session: Esc exits it - Gesture = 2, // an uncommitted delta (entity being drawn, body being dragged): Esc reverts it - Transient = 3, // a value field or a popup menu: Esc closes just that -}; - -struct CadInteractionState { // the four bits routing actually needs - bool value_field_open{false}; - bool gesture_active{false}; - bool tool_armed{false}; - bool has_selection{false}; -}; - -constexpr CadLevel cad_escape_level(const CadInteractionState& s) -{ - if (s.value_field_open) return CadLevel::Transient; - if (s.gesture_active) return CadLevel::Gesture; - if (s.tool_armed) return CadLevel::Tool; - return CadLevel::Idle; -} -``` - -The rule is a `constexpr` free function over a POD, not a method on the panel, so the ordering -that is the entire contract is checkable without a window, a GL context or an event loop. Five -`static_assert`s in the header do exactly that, at compile time. - -**Strict invariant.** No level of Esc deletes a feature, discards a sketch that holds geometry, -or rolls history back. Destroying work needs a gesture that says so: - -| To destroy | Gesture | -|---|---| -| a feature | Delete / Backspace on an explicit selection | -| a drawn sketch | the ribbon's ✗ Cancel, which asks first | -| the last committed change | Ctrl+Z | - -## 2. Event routing - -**`OnKeyDown(WXK_ESCAPE)`** — `DesignPanel`'s `wxEVT_CHAR_HOOK`, one line: - -```cpp -if (key == WXK_ESCAPE) { escape(); return; } -``` - -Every Esc in the tab goes through it, whatever holds focus. `DesignPanel::escape_level()` answers -the four questions of `CadInteractionState` about this panel; `DesignPanel::escape()` acts on the -one level that answer names, and on no other: - -| Level | What one press does | What it must not touch | -|---|---|---| -| `Transient` | close the value field (`cancel_value` / `inline_cancel`) | the tool, which stays armed | -| `Gesture` | drop the clicks of the entity being drawn, or put a moved body back at the pose it had when the gizmo appeared | everything already committed | -| `Tool` | discard a feature card's *candidate*; drop an armed sketch tool to Select; end Constrain | committed features; entities already drawn | -| `Idle` | clear the selection (model and sketch); leave a sketch session **only if it is empty** | a sketch holding geometry — it is left through Finish or Cancel | - -A sketch *session* is deliberately not a `Tool`. It is the environment the Idle level lives in, -which is what makes the destructive path unrepresentable rather than merely unlikely. - -**`OnRightDown` / `OnRightUp`** — `DesignCanvas::set_on_context_menu`, bound after `GLCanvas3D`'s -own handlers so it can consume the event before them: - -```cpp -RIGHT_DOWN: remember the press position and the clock, then Skip() // the canvas still seeds the orbit - -RIGHT_UP: terminated = sketch_tool.take_right_consumed(); // read-and-clear, always - is_click = drift <= 3 px && dt <= 200 ms; // both budgets, or it was navigation - if (callback && !terminated && !inline_busy && is_click) { - select_at_screen(press.x, press.y); // raycast at the PRESS, not the release - on_context_menu(ClientToScreen(press)); - return; // consumed - } - Skip(); // orbit / pan / the handlers underneath -``` - -Two independent budgets because the two failure modes are independent: drift alone still popped a -menu at the end of a slow, careful orbit. `take_right_consumed()` is how a right-click that -already meant something to the armed sketch tool (terminate a chain, drop an edit-op) declines to -also mean "open a menu". - -## 3. Transition table - -`sel` = something is picked. Blank = the input does nothing at that state. - -| State | Left-click | Right-click | Esc | Enter | -|---|---|---|---|---| -| **Idle — model view** | pick / escalate the pick | offer menu for what is under the cursor | clear the selection | — | -| **Idle — sketch, empty** | pick | sketch offer menu | leave the session (nothing to lose) | Finish sketch | -| **Idle — sketch, drawn** | pick | sketch offer menu | clear the selection; status says the sketch is kept | Finish sketch | -| **Tool — feature card** | pick the card's next reference | offer menu | discard the candidate, close the card | commit the feature | -| **Tool — sketch tool armed** | place the first point | drop the tool to Select | drop the tool to Select | — | -| **Tool — constrain** | pick an entity | offer menu | end the session | apply | -| **Gesture — drawing** | place the next point | terminate the chain (keep what is drawn) | drop the in-progress entity, tool stays armed | commit the entity as drawn | -| **Gesture — moving a body** | drop the body here | end the move | revert to the pose at move-start | keep the placement | -| **Transient — value field** | — | — | close the field, tool stays armed | commit the value, advance the chain | -| **Transient — popup menu** | run the entry | — | close the menu | run the highlighted entry | -| **any** | — | — | *never* deletes, discards or rolls back | — | - -Right-hold-and-drag is not in the table on purpose: past 3 px or 200 ms it is navigation, and -navigation does not transition the state machine. - -## 4. Visual scaffolding - -Entering a sketch changes three things at once, so the state is legible from across the room: - -- **Banner.** A teal strip across the top of the viewport: `Editing: Sketch N · N = look normal to - the plane · Finish or Cancel in the toolbar`. Indicator only — Confirm and Cancel stay on the one - ribbon action bar, per the Design UX contract. It is a sibling above the canvas, not a floating - child over it: a child window over a `wxGLCanvas` is a native window on GTK and does not reliably - stack over GL, and this banner's job is to be unmissable rather than clever. -- **The printer bed is muted.** A plate grid and a sketch grid are the same visual language, and - reading one as the other is how a sketch gets drawn against the wrong reference. The view - checkbox remains the stored preference and is restored on the way out; ticking it mid-sketch - still shows the bed, because that is a deliberate act and this is only a default. -- **`N` looks normal to the plane**, keeping the current zoom, with the plane's own y axis as up. - Sketch key map only — in Feature mode the navigator orb owns orientation. - -## 5. Context menu content - -The offer is generated from `docs/CAD/ux/tool_atlas.json`; its 8-row shape and permanent row -indices are ratified and are not changed here. Checked against the per-context vocabularies asked -for in the 2026-09-05 interaction brief, the atlas already carries all of them except two, both on -a planar face: - -| Asked for | Status | -|---|---| -| Revolve on a planar face | **not offered, and should not be**: `revolve` accepts `sk_loop` only, because the kernel takes a sketch profile — a face is not one | -| Offset Face | offered as **Thicken** (`thicken`, accepts `face_planar`); `surf_offset` is the sheet-body verb and accepts `body_sheet` | - -View and document actions — Zoom to Fit, View Isometric, Clear Selection, Finish Sketch, Normal to -Sketch — stay in chrome by the atlas's own rule: the offer describes verbs that consume a -*selection*, and these act on the document or the camera. Esc covers Clear Selection, `N` covers -Normal to Sketch, and the ribbon covers Finish. diff --git a/docs/CAD/ux/mockups/cmp_12__edge_str.svg b/docs/CAD/ux/mockups/cmp_12__edge_str.svg deleted file mode 100644 index 3e641e90ec..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_12__face_planar.svg b/docs/CAD/ux/mockups/cmp_12__face_planar.svg deleted file mode 100644 index 85809d5bf6..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_12__sk_line.svg b/docs/CAD/ux/mockups/cmp_12__sk_line.svg deleted file mode 100644 index 6535c9fe77..0000000000 --- a/docs/CAD/ux/mockups/cmp_12__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__edge_str.svg b/docs/CAD/ux/mockups/cmp_8__edge_str.svg deleted file mode 100644 index 2c41ce74fc..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__face_planar.svg b/docs/CAD/ux/mockups/cmp_8__face_planar.svg deleted file mode 100644 index 5a58e2fb72..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/cmp_8__sk_line.svg b/docs/CAD/ux/mockups/cmp_8__sk_line.svg deleted file mode 100644 index 4ca4000d59..0000000000 --- a/docs/CAD/ux/mockups/cmp_8__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__art.svg b/docs/CAD/ux/mockups/fresh__art.svg deleted file mode 100644 index a54dd49b43..0000000000 --- a/docs/CAD/ux/mockups/fresh__art.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetText / imported art selected — pick what to do with itFresh document · 8 slotsABCModify2Text / imported art \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__art__modify.svg b/docs/CAD/ux/mockups/fresh__art__modify.svg deleted file mode 100644 index 184611c682..0000000000 --- a/docs/CAD/ux/mockups/fresh__art__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__bodies_2.svg b/docs/CAD/ux/mockups/fresh__bodies_2.svg deleted file mode 100644 index f282bef03a..0000000000 --- a/docs/CAD/ux/mockups/fresh__bodies_2.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetTwo bodies selected — pick what to do with itFresh document · 8 slotsMeasureDeleteDelTwo bodies \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_sheet.svg b/docs/CAD/ux/mockups/fresh__body_sheet.svg deleted file mode 100644 index 635b2f6aa6..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_sheet.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSheet body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Sheet body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg b/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg deleted file mode 100644 index 0cd330046d..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_sheet__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_solid.svg b/docs/CAD/ux/mockups/fresh__body_solid.svg deleted file mode 100644 index ef21e2b8e2..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSolid body selected — pick what to do with itFresh document · 8 slotsMeasureModify2Solid body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__body_solid__modify.svg b/docs/CAD/ux/mockups/fresh__body_solid__modify.svg deleted file mode 100644 index 8b5d1485a0..0000000000 --- a/docs/CAD/ux/mockups/fresh__body_solid__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__coordsys.svg b/docs/CAD/ux/mockups/fresh__coordsys.svg deleted file mode 100644 index e20d08d000..0000000000 --- a/docs/CAD/ux/mockups/fresh__coordsys.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCoordinate system selected — pick what to do with itFresh document · 8 slotsModify2Coordinate system \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__coordsys__modify.svg b/docs/CAD/ux/mockups/fresh__coordsys__modify.svg deleted file mode 100644 index b6b4871d16..0000000000 --- a/docs/CAD/ux/mockups/fresh__coordsys__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_axis.svg b/docs/CAD/ux/mockups/fresh__datum_axis.svg deleted file mode 100644 index 8174807ceb..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_axis.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDatum axis selected — pick what to do with itFresh document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg b/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg deleted file mode 100644 index cba7005358..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_axis__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane.svg b/docs/CAD/ux/mockups/fresh__datum_plane.svg deleted file mode 100644 index ffabd59969..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDatum plane selected — pick what to do with itFresh document · 8 slotsSketchShift+SReference2Modify2Datum plane \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg b/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg deleted file mode 100644 index 9ac26e4ce1..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg b/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg deleted file mode 100644 index b42479441a..0000000000 --- a/docs/CAD/ux/mockups/fresh__datum_plane__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_circ.svg b/docs/CAD/ux/mockups/fresh__edge_circ.svg deleted file mode 100644 index 3e72544c04..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_circ.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCircular edge selected — pick what to do with itFresh document · 8 slotsMeasureCircular edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_str.svg b/docs/CAD/ux/mockups/fresh__edge_str.svg deleted file mode 100644 index c4e54d5335..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetStraight edge selected — pick what to do with itFresh document · 8 slotsReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__edge_str__reference.svg b/docs/CAD/ux/mockups/fresh__edge_str__reference.svg deleted file mode 100644 index 80dd7a877a..0000000000 --- a/docs/CAD/ux/mockups/fresh__edge_str__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_cyl.svg b/docs/CAD/ux/mockups/fresh__face_cyl.svg deleted file mode 100644 index d2335e4177..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_cyl.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCylindrical face selected — pick what to do with itFresh document · 8 slotsReference3EditCylindrical face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg b/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg deleted file mode 100644 index 7cb83afb56..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_cyl__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_other.svg b/docs/CAD/ux/mockups/fresh__face_other.svg deleted file mode 100644 index d8dcfb96ab..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_other.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCurved face selected — pick what to do with itFresh document · 8 slotsMeasureEditCurved face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_planar.svg b/docs/CAD/ux/mockups/fresh__face_planar.svg deleted file mode 100644 index a66268fc9a..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetPlanar face selected — pick what to do with itFresh document · 8 slotsSketchShift+SExtrudeShift+EReference4EditPlanar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__face_planar__reference.svg b/docs/CAD/ux/mockups/fresh__face_planar__reference.svg deleted file mode 100644 index 9aa608a5e7..0000000000 --- a/docs/CAD/ux/mockups/fresh__face_planar__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__none.svg b/docs/CAD/ux/mockups/fresh__none.svg deleted file mode 100644 index 56ac028b74..0000000000 --- a/docs/CAD/ux/mockups/fresh__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__none__reference.svg b/docs/CAD/ux/mockups/fresh__none__reference.svg deleted file mode 100644 index 0492aa6de0..0000000000 --- a/docs/CAD/ux/mockups/fresh__none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent.svg b/docs/CAD/ux/mockups/fresh__sk_2ent.svg deleted file mode 100644 index dd02122149..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetTwo sketch entities selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg deleted file mode 100644 index 98e984bff2..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg deleted file mode 100644 index 926594bb86..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg deleted file mode 100644 index 242332967e..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg b/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg deleted file mode 100644 index aa105c3a9e..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_2ent__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc.svg b/docs/CAD/ux/mockups/fresh__sk_arc.svg deleted file mode 100644 index 0712508411..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch arc or circle selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__create.svg b/docs/CAD/ux/mockups/fresh__sk_arc__create.svg deleted file mode 100644 index d22d916e60..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg b/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg deleted file mode 100644 index cf3fc2450f..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg b/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg deleted file mode 100644 index cfbe0a1042..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_arc__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line.svg b/docs/CAD/ux/mockups/fresh__sk_line.svg deleted file mode 100644 index e40d823e13..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch line selected — pick what to do with itFresh document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__create.svg b/docs/CAD/ux/mockups/fresh__sk_line__create.svg deleted file mode 100644 index 1a6f7b561c..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg b/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg deleted file mode 100644 index 3fce662ba1..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetDress-up — pick oneFresh document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__modify.svg b/docs/CAD/ux/mockups/fresh__sk_line__modify.svg deleted file mode 100644 index 26318535ef..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_line__reference.svg b/docs/CAD/ux/mockups/fresh__sk_line__reference.svg deleted file mode 100644 index 2abc91fc99..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_line__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop.svg b/docs/CAD/ux/mockups/fresh__sk_loop.svg deleted file mode 100644 index 58eaa9e4fb..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetClosed sketch loop selected — pick what to do with itFresh document · 8 slotsAdd material5Modify2Closed sketch loop \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop__add.svg b/docs/CAD/ux/mockups/fresh__sk_loop__add.svg deleted file mode 100644 index c6e6c90701..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetAdd material — pick oneFresh document · 8 slotsExtrudeShift+ERevolveShift+RSurface ExtrudeShift+GSurface RevolveSurface FillClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg b/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg deleted file mode 100644 index 416e62d7cd..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_loop__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetModify — pick oneFresh document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none.svg b/docs/CAD/ux/mockups/fresh__sk_none.svg deleted file mode 100644 index ce7604c47d..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch, nothing picked selected — pick what to do with itFresh document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none__create.svg b/docs/CAD/ux/mockups/fresh__sk_none__create.svg deleted file mode 100644 index 06994f9517..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_none__reference.svg b/docs/CAD/ux/mockups/fresh__sk_none__reference.svg deleted file mode 100644 index e4e558bbd9..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point.svg b/docs/CAD/ux/mockups/fresh__sk_point.svg deleted file mode 100644 index 65acf94ac7..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetSketch point selected — pick what to do with itFresh document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point__create.svg b/docs/CAD/ux/mockups/fresh__sk_point__create.svg deleted file mode 100644 index fbe094d147..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetCreate — pick oneFresh document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__sk_point__reference.svg b/docs/CAD/ux/mockups/fresh__sk_point__reference.svg deleted file mode 100644 index 8b02eba29f..0000000000 --- a/docs/CAD/ux/mockups/fresh__sk_point__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__vertex.svg b/docs/CAD/ux/mockups/fresh__vertex.svg deleted file mode 100644 index 1e1661d6aa..0000000000 --- a/docs/CAD/ux/mockups/fresh__vertex.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetVertex selected — pick what to do with itFresh document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/CAD/ux/mockups/fresh__vertex__reference.svg b/docs/CAD/ux/mockups/fresh__vertex__reference.svg deleted file mode 100644 index aad3d46b6e..0000000000 --- a/docs/CAD/ux/mockups/fresh__vertex__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetReference — pick oneFresh document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/gen_offer_mockups.py b/docs/CAD/ux/mockups/gen_offer_mockups.py deleted file mode 100644 index 6ddd4caae4..0000000000 --- a/docs/CAD/ux/mockups/gen_offer_mockups.py +++ /dev/null @@ -1,884 +0,0 @@ -#!/usr/bin/env python3 -"""Render the object-driven tool offer from docs/ux/tool_atlas.json. - -Fork-neutral on purpose: this file and everything it emits name no product, so the -two forks carry byte-identical copies (the charter itself is the only doc that -substitutes the product name). - -Every mockup in docs/ux/mockups/ and the review page docs/ux/offer_atlas.html are -generated by this script. Nothing is hand-drawn: the point of the offer is that a -tool's address never changes, and a human drawing 40-odd states by hand is exactly -how an address quietly changes. - - python3 docs/ux/mockups/gen_offer_mockups.py - -It fails loudly rather than rendering a broken map: an unknown slot, an unknown -selection id in `accepts`, or one address holding two different verbs for the same -selection is an error, not a warning. - -SVG on purpose. There is no rsvg/inkscape/cairosvg on the build box and -ImageMagick would rasterise through its own weak internal renderer; SVG renders -exactly in a browser at any zoom and stays diffable in git. Rasterise later if -slides need it. -""" - -import json -import re -import math -import os -import sys -from collections import defaultdict - -HERE = os.path.dirname(os.path.abspath(__file__)) -UX = os.path.dirname(HERE) -ATLAS = os.path.join(UX, "tool_atlas.json") - -# The reach target from the charter (L11 / 6.1): if the ring plus a real part do not -# fit here, the design has failed before it is built. -W, H = 1366, 768 - -C = { - "app": "#1a1d21", "chrome": "#23272d", "panel": "#20242a", "line": "#31363d", - "vp0": "#2f353d", "vp1": "#242930", "grid": "#333a43", - "text": "#e7ecf1", "muted": "#8e9aa7", "dim": "#5f6a76", - "top": "#93a1b1", "left": "#6f7b89", "right": "#5a6472", "edge": "#39414b", - "hi": "#f5a623", "hi_soft": "#f5a62333", "sheet": "#7fa8c9", - "ring": "#171a1e", "chip": "#2e343c", "chip_line": "#3c444e", - "key": "#454f5b", "accent": "#4f9bd9", "empty": "#2a2f36", -} - - -# ---------------------------------------------------------------- glyphs -# Each glyph draws inside a 24x24 box centred on (0,0) — i.e. -12..12. -def _g(body): - return body - - -GLYPHS = { - # model - "sketch": '', - "extrude": '', - "revolve": '', - "sweep": '', - "loft": '', - "thicken": '', - "rib": '', - "boolean": '', - "hole": '', - "thread": '', - "shell": '', - "cut": '', - "split": '', - "fillet": '', - "chamfer": '', - "draft": '', - "surf_off": '', - "pattern": '', - "mirror": '', - "pat_curve": '', - "move": '', - "mate": '', - "align": '', - "plane": '', - "axis": '', - "csys": '', - "helix": '', - "project": '', - "measure": '', - "mass": '', - "interfere": '', - "edit": '', - "del_face": '', - "colour": '', - "delete": '', - # sketch primitives - "sk_line": '', - "sk_rect": '', - "sk_circle": '', - "sk_arc": '', - "sk_slot": '', - "sk_ell": '', - "sk_spline": '', - "sk_poly": '', - "sk_point": '', - "sk_offset": '', - "sk_trim": '', - "sk_ext": '', - "sk_mir": '', - "sk_move": '', - "sk_dim": '', - "sk_lock": '', - "sk_constr": '', - # families (used when a slot holds more than one verb) - "fam_create": '', - "fam_add": '', - "fam_remove": '', - "fam_dressup": '', - "fam_repeat": '', - "fam_transform": '', - "fam_reference": '', - # Deliberately NOT the bare pencil: create/sketch already owns that shape and the two slots - # are adjacent (N and NW). A pencil over a solid reads as "change the thing that exists". - "fam_modify": '' - '', -} - -VERB_GLYPH = { - "sketch": "sketch", "extrude": "extrude", "revolve": "revolve", "sweep": "sweep", - "loft": "loft", "thicken": "thicken", "rib": "rib", "boolean": "boolean", - "surf_extrude": "extrude", "surf_revolve": "revolve", "surf_loft": "loft", - "surf_fill": "surf_off", "thicken_surf": "thicken", "hole": "hole", "thread": "thread", - "shell": "shell", "cut": "cut", "split": "split", "fillet": "fillet", - "chamfer": "chamfer", "draft": "draft", "surf_offset": "surf_off", - "pattern": "pattern", "mirror": "mirror", "pat_curve": "pat_curve", - "transform": "move", "mate": "mate", "align": "align", "plane": "plane", - "axis": "axis", "coordsys_v": "csys", "helix": "helix", "project": "project", - "measure": "measure", "mass_props": "mass", "interference": "interfere", - "edit_feature": "edit", "delete_face": "del_face", "colour": "colour", "delete": "delete", - "sk_line_t": "sk_line", "sk_rect": "sk_rect", "sk_circle": "sk_circle", - "sk_arc_t": "sk_arc", "sk_slot": "sk_slot", "sk_ellipse": "sk_ell", - "sk_spline": "sk_spline", "sk_polygon": "sk_poly", "sk_point_t": "sk_point", - "sk_offset": "sk_offset", "sk_trim": "sk_trim", "sk_fillet": "fillet", - "sk_chamfer": "chamfer", "sk_mirror": "sk_mir", "sk_move": "sk_move", - "sk_dimension": "sk_dim", "sk_constrain": "sk_lock", "sk_construct": "sk_constr", - "sk_extend": "sk_ext", "sk_delete": "delete", -} - - -def glyph(name, cx, cy, colour, scale=1.0, sw=1.6): - body = GLYPHS.get(name, '') - return (f'{body}') - - -# ---------------------------------------------------------------- iso scene -COS30, SIN30 = math.cos(math.radians(30)), math.sin(math.radians(30)) - - -def iso(x, y, z, ox, oy, s=1.0): - return (ox + (x - y) * COS30 * s, oy + (x + y) * SIN30 * s - z * s) - - -def poly(pts, fill, stroke=None, extra=""): - d = " ".join(f"{x:.1f},{y:.1f}" for x, y in pts) - # Only emit our own stroke-width when the caller has not supplied one: a duplicate - # attribute is last-one-wins in a browser but invalid markup, and it is exactly the - # kind of thing a stricter renderer refuses outright. - if stroke: - st = f' stroke="{stroke}"' + ("" if "stroke-width" in extra else ' stroke-width="1"') - else: - st = ' stroke="none"' - return f'' - - -def box(ox, oy, w=150, d=105, h=52, s=1.0, hi=None): - """Three visible faces of a box. `hi` names the face/edge to highlight.""" - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - top = [P(0, 0, h), P(w, 0, h), P(w, d, h), P(0, d, h)] - left = [P(0, d, h), P(w, d, h), P(w, d, 0), P(0, d, 0)] - right = [P(w, 0, h), P(w, d, h), P(w, d, 0), P(w, 0, 0)] - out = [ - poly(left, C["left"], C["edge"]), - poly(right, C["right"], C["edge"]), - poly(top, C["hi"] if hi == "top" else C["top"], C["edge"]), - ] - if hi == "top": - out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) - if hi == "front_edge": - a, b = P(0, d, h), P(w, d, h) - out.append(f'') - if hi == "vertex": - v = P(w, d, h) - out.append(f'') - if hi == "whole": - out.append(poly(top, "none", "#ffd07a", ' stroke-width="2.5"')) - out.append(poly(left, "none", "#ffd07a", ' stroke-width="2.5"')) - out.append(poly(right, "none", "#ffd07a", ' stroke-width="2.5"')) - return "".join(out), P - - -def bore(P, cx, cy, h, r=22, s=1.0, hi=False): - """A cylindrical bore through the top face, drawn as ellipse + wall.""" - c = P(cx, cy, h) - rx, ry = r * COS30 * 2 * s, r * SIN30 * 2 * s - col = C["hi"] if hi else "#20252b" - wall = C["hi"] if hi == "wall" else "#3b434d" - return (f'' - f'' - + (f'' if hi else "")), c - - -def scene(kind, ox, oy): - """Return (svg, anchor) for a selection kind. Anchor = where the ring centres.""" - s = 1.0 - if kind == "origin": - # A document with nothing in it: the three origin planes are all there is to click. - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g = poly([P(-70, -70, 0), P(70, -70, 0), P(70, 70, 0), P(-70, 70, 0)], - "#4f9bd91f", "#4f9bd977", ' stroke-width="1.5" stroke-dasharray="6 4"') - g += poly([P(-70, 0, -70), P(70, 0, -70), P(70, 0, 70), P(-70, 0, 70)], - "#e05c5c14", "#e05c5c66", ' stroke-width="1.5" stroke-dasharray="6 4"') - g += poly([P(0, -70, -70), P(0, 70, -70), P(0, 70, 70), P(0, -70, 70)], - "#5ce07a14", "#5ce07a66", ' stroke-width="1.5" stroke-dasharray="6 4"') - return g, P(0, 0, 0) - if kind == "empty": - g, P = box(ox, oy, s=s) - return g, P(75, 52, 26) - if kind == "box_top": - g, P = box(ox, oy, s=s, hi="top") - return g, P(75, 52, 52) - if kind == "box_whole": - g, P = box(ox, oy, s=s, hi="whole") - return g, P(75, 52, 26) - if kind == "box_edge": - g, P = box(ox, oy, s=s, hi="front_edge") - return g, P(75, 105, 52) - if kind == "box_vertex": - g, P = box(ox, oy, s=s, hi="vertex") - return g, P(150, 105, 52) - if kind in ("box_bore", "box_bore_rim"): - g, P = box(ox, oy, s=s) - b, c = bore(P, 75, 52, 52, hi=("wall" if kind == "box_bore" else True)) - return g + b, c - if kind == "box_fillet_face": - g, P = box(ox, oy, s=s) - a, b = P(0, 0, 52), P(0, 105, 52) - g += (f'') - return g, P(0, 52, 52) - if kind == "sheet": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - pts = [P(0, 0, 40), P(150, 0, 55), P(150, 105, 30), P(0, 105, 18)] - return (poly(pts, C["sheet"], "#ffd07a", ' stroke-width="2.5" opacity="0.85"'), - P(75, 52, 36)) - if kind == "two_boxes": - g1, P1 = box(ox - 60, oy - 10, w=110, d=80, h=44, hi="whole") - g2, P2 = box(ox + 70, oy + 26, w=95, d=70, h=60, hi="whole") - return g1 + g2, (ox + 42, oy + 6) - if kind == "datum": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - pts = [P(-25, -25, 70), P(175, -25, 70), P(175, 130, 70), P(-25, 130, 70)] - g += poly(pts, "#4f9bd933", C["hi"], ' stroke-width="2.5" stroke-dasharray="6 4"') - return g, P(75, 52, 70) - if kind == "axis": - g, P = box(ox, oy, s=s) - a, b = P(-30, 52, 52), P(180, 52, 52) - g += (f'') - return g, P(75, 52, 52) - if kind == "csys": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - o = P(0, 0, 52) - for tgt, col in ((P(60, 0, 52), "#e05c5c"), (P(0, 60, 52), "#5ce07a"), (P(0, 0, 112), "#5c9ce0")): - g += (f'') - g += f'' - return g, o - if kind == "art": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - c = P(75, 52, 52) - g += (f'' - f'ABC') - return g, c - if kind == "loop": - P = lambda x, y, z: iso(x, y, z, ox, oy, s) - g, _ = box(ox, oy, s=s) - pts = [P(28, 22, 52), P(122, 22, 52), P(122, 83, 52), P(28, 83, 52)] - g += poly(pts, C["hi_soft"], C["hi"], ' stroke-width="3"') - return g, P(75, 52, 52) - # --- sketch mode: flat, camera normal to the plane - gx, gy = ox - 30, oy - 10 - grid = "".join( - f'' - for i in range(11)) + "".join( - f'' - for i in range(16)) - if kind == "sk_empty": - return grid, (gx, gy) - if kind == "sk_line": - return (grid + f'' - f'' - f'', (gx, gy + 10)) - if kind == "sk_arc": - return (grid + f'', (gx, gy)) - if kind == "sk_point": - return (grid + f'', (gx, gy)) - if kind == "sk_two": - return (grid + f'' - f'', (gx, gy + 5)) - return grid, (gx, gy) - - -# ---------------------------------------------------------------- app chrome -def chrome(title, status, mode="model", empty_doc=False): - tabs = ["Prepare", "Preview", "Design"] - g = [f'', - f'' - f'' - f'', - f'', - f''] - x = 24 - for t in tabs: - on = (t == "Design") - g.append(f'{t}') - if on: - g.append(f'') - x += len(t) * 9 + 34 - # toolbar - g.append(f'' - f'') - fams = (["sketch", "extrude", "hole", "fillet", "pattern", "boolean", "plane", "move", "measure"] - if mode == "model" else - ["sk_line", "sk_rect", "sk_circle", "sk_arc", "sk_slot", "sk_spline", "sk_dim", "sk_trim", "sk_lock"]) - for i, gl in enumerate(fams): - cx = 40 + i * 46 - g.append(f'') - g.append(glyph(gl, cx, 68, C["muted"], 0.62, 1.7)) - # left rail - g.append(f'' - f'') - g.append(f'FEATURES') - # A "fresh document" mockup that shows six existing features is a lie, and it is the one - # state the group will look at hardest — it is the first-run picture (B5). - tree = ([] if empty_doc else - [("Sketch1", 0), ("Extrude1", 0), ("Hole1", 1), ("Fillet1", 1), ("Sketch2", 0), ("Extrude2", 0)]) - if empty_doc: - g.append(f'nothing yet') - for i, (n, ind) in enumerate(tree): - yy = 150 + i * 26 - g.append(glyph("sketch" if n.startswith("Sketch") else "extrude", 30 + ind * 14, yy - 4, C["dim"], 0.42, 1.8)) - g.append(f'{n}') - # status bar - g.append(f'' - f'{status}') - g.append(f'{title}') - return "".join(g) - - -# ---------------------------------------------------------------- the ring -def ring(cx, cy, items, capacity, sel_name, radius=134): - """items: dict angle_index -> (glyph, label, key, count) or None for an empty slot.""" - # The scrim is deliberately faint. §4.1: the offer "never blocks the view of what it acts - # on" — at 0.55 the disc swallowed the very face the ring was opened on, which is the rule - # failing in its own mockup. - g = [f'', - f'', - f''] - step = 360.0 / capacity - for i in range(capacity): - ang = math.radians(-90 + i * step) - px, py = cx + radius * math.cos(ang), cy + radius * math.sin(ang) - it = items.get(i) - if not it: - g.append(f'') - continue - gl, label, key, count = it - g.append(f'') - g.append(glyph(gl, px, py - 2, C["text"], 0.92, 1.7)) - g.append(f'{label}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - if count and count > 1: - g.append(f'' - f'{count}') - # The selection name sits on the LOWER rim of the centre hole, not above it: above, it - # landed on top of the north slot's shortcut chip and hid it. Below, the pick stays - # visible through the hole and the pill is clear of the south chip at cy+104. - w = 13 + len(sel_name) * 6.9 - g.append(f'' - f'{sel_name}') - return "".join(g) - - -# ---------------------------------------------------------------- enumeration -def load(): - with open(ATLAS, encoding="utf-8") as f: - return json.load(f) - - -def validate(A): - slot_ids = {s["id"] for s in A["slots"]} - sel_ids = {s["id"] for s in A["selections"]} - errs = [] - seen = {} - for v in A["verbs"]: - if v["slot"] not in slot_ids: - errs.append(f'{v["id"]}: unknown slot {v["slot"]!r}') - for a in v["accepts"]: - if a not in sel_ids: - errs.append(f'{v["id"]}: accepts unknown selection {a!r}') - if v["id"] in seen: - errs.append(f'{v["id"]}: duplicate verb id') - seen[v["id"]] = v["slot"] - if errs: - sys.exit("tool_atlas.json is inconsistent:\n " + "\n ".join(errs)) - return slot_ids, sel_ids - - -def eligible(A, sel_id, doc): - sel = next(s for s in A["selections"] if s["id"] == sel_id) - out = [] - for v in A["verbs"]: - if v.get("mode", "model") != sel["mode"]: - continue - if sel_id not in v["accepts"]: - continue - n = v.get("needs") or {} - if n.get("bodies", 0) > doc["bodies"]: - continue - if n.get("sketches", 0) > doc["sketches"]: - continue - if n.get("sheet") and not doc["sheet"]: - continue - out.append(v) - return out - - -def by_slot(A, verbs): - order = [s["id"] for s in A["slots"]] - d = defaultdict(list) - for v in verbs: - d[v["slot"]].append(v) - return {k: d[k] for k in order if d[k]} - - -def ring_items(A, grouped): - order = [s["id"] for s in A["slots"]] - slot_label = {s["id"]: s["label"] for s in A["slots"]} - items = {} - for i, sid in enumerate(order): - vs = grouped.get(sid) - if not vs: - continue - if len(vs) == 1: - v = vs[0] - items[i] = (VERB_GLYPH.get(v["id"], "fam_" + sid), v["name"], v.get("key"), 1) - else: - items[i] = ("fam_" + sid, slot_label[sid], None, len(vs)) - return items - - -# ---------------------------------------------------------------- rendering -def menu(cx, cy, header, rows, submenu=None, sub_at=None): - """Vertical list form of the offer. rows: (glyph, name, key, count, enabled, reason). - - The invariant is unchanged — a verb has one permanent row index, and rows that do not - apply are DISABLED IN PLACE, never removed. What changes against the ring is what an - unavailable slot can say: an empty circle says nothing, a greyed row says its own name - and the reason it is grey, in the words the product already ships. - """ - RW, RH, HD = 324, 34, 38 - # The reason line is the whole point of a disabled row, so it must FIT: at 10px italic a - # glyph is ~4.9px, and anything past the box edge is a promise the layout does not keep. - fit = int((RW - 62) / 4.9) - x, y = cx + 26, cy - 30 - h = HD + len(rows) * RH + 10 - if y + h > H - 44: - y = max(100, H - 44 - h) - g = [f'', - f'', - f'{header.upper()}', - f''] - # a leader from the pick point to the menu, so the list is visibly ABOUT that geometry - g.insert(0, f'') - g.insert(0, f'') - for i, (gl, name, key, count, on, reason) in enumerate(rows): - ry = y + HD + i * RH - op = "1" if on else "0.34" - if on and i == 0: - g.append(f'') - g.append(f'') - g.append(glyph(gl, x + 26, ry + RH / 2, C["text"], 0.72, 1.7)) - g.append(f'{name}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - elif count and count > 1: - g.append(f'') - g.append(f'{count}') - g.append('') - if not on and reason: - r = reason if len(reason) <= fit else reason[:fit - 1].rstrip(" ,—-") + "…" - g.append(f'{r}') - if submenu: - sy = y + HD + (sub_at or 0) * RH - 6 - sh = 12 + len(submenu) * RH - sx = x + RW + 8 - g.append(f'') - g.append(f'') - for i, (gl, name, key, _c, on, _r) in enumerate(submenu): - ry = sy + 6 + i * RH - g.append(f'') - g.append(glyph(gl, sx + 24, ry + RH / 2, C["text"], 0.72, 1.7)) - g.append(f'{name}') - if key: - kw = 13 + len(key) * 6.6 - g.append(f'' - f'{key}') - g.append('') - return "".join(g) - - -OVERFLOWS = [] # (selection, doc state, family, verbs that did not fit the sub-ring) - - -def svg_doc(inner): - return (f'{inner}') - - -def render_list_state(A, sel, doc, expand=None): - """The vertical-list form: every family row always present, in the same order, with the - ones that do not apply disabled and carrying their reason.""" - verbs = eligible(A, sel["id"], doc) - grouped = by_slot(A, verbs) - fresh = doc["bodies"] == 0 and doc["sketches"] == 0 - shape = "origin" if (fresh and sel["shape"] == "empty") else sel["shape"] - art, (ax, ay) = scene(shape, 620, 360) - rows, sub, sub_at = [], None, None - for idx, s in enumerate(A["slots"]): - vs = grouped.get(s["id"], []) - if len(vs) == 1: - v = vs[0] - rows.append((VERB_GLYPH.get(v["id"], "fam_" + s["id"]), v["name"], v.get("key"), 1, True, None)) - elif len(vs) > 1: - rows.append(("fam_" + s["id"], s["label"], None, len(vs), True, None)) - if expand == s["id"]: - sub_at = idx - sub = [(VERB_GLYPH.get(v["id"], "fam_" + s["id"]), v["name"], v.get("key"), 1, True, None) - for v in vs] - else: - # Disabled in place, with the product's own refusal text — the thing an empty - # slot in the ring could never say. - cands = [v for v in A["verbs"] - if v["slot"] == s["id"] and v.get("mode", "model") == sel["mode"]] - why = next((v["refusal"] for v in cands if v.get("refusal")), None) - rows.append(("fam_" + s["id"], s["label"], None, 0, False, why)) - status = ("Right-click the geometry to see what you can do with it" if not expand - else f'{sel["name"]} — pick one') - inner = chrome(f'{doc["name"]} · vertical list', status, sel["mode"], empty_doc=fresh) - inner += art - inner += menu(ax, ay, sel["name"], rows, sub, sub_at) - return svg_doc(inner) - - -def render_state(A, sel, doc, capacity=8, secondary=None): - verbs = eligible(A, sel["id"], doc) - grouped = by_slot(A, verbs) - anchor_x, anchor_y = 810, 400 - fresh = doc["bodies"] == 0 and doc["sketches"] == 0 - shape = "origin" if (fresh and sel["shape"] == "empty") else sel["shape"] - art, (ax, ay) = scene(shape, anchor_x - 90, anchor_y - 40) - if secondary: - vs = grouped[secondary] - # A sub-ring ANCHORS ON ITS PARENT'S DIRECTION. Fanning from north instead put Extrude - # at N — Create's address in the primary map — so the second level contradicted the - # first. Anchored, an address is two consistent strokes: Add material is NE, and the - # first verb of Add material is NE again. - base = [s["id"] for s in A["slots"]].index(secondary) - overflow = [] - if len(vs) > capacity: - # Do NOT wrap: (base+i) % capacity would quietly put verb 9 on top of verb 1, which - # is the invariant failing silently — the one outcome worse than an ugly ring. Show - # what fits, mark the rest, and report it. - overflow = vs[capacity - 1:] - vs = vs[:capacity - 1] - items = {(base + i) % capacity: - (VERB_GLYPH.get(v["id"], "fam_" + secondary), v["name"], v.get("key"), 1) - for i, v in enumerate(vs)} - if overflow: - items[(base + capacity - 1) % capacity] = ("fam_" + secondary, "More", None, len(overflow)) - OVERFLOWS.append((sel["name"], doc["id"], secondary, [v["name"] for v in overflow])) - label = next(s["label"] for s in A["slots"] if s["id"] == secondary) - sel_name = f'{sel["name"]} · {label}' - status = f'{label} — pick one' - else: - items = ring_items(A, grouped) - sel_name = sel["name"] - status = ("Click a face or a reference plane, then a tool" - if sel["id"] == "none" else f'{sel["name"]} selected — pick what to do with it') - inner = chrome(f'{doc["name"]} · {capacity} slots', status, sel["mode"], empty_doc=fresh) - inner += art - inner += ring(ax, ay, items, capacity, sel_name) - return svg_doc(inner), verbs, grouped - - -def main(): - A = load() - validate(A) - docs = {d["id"]: d for d in A["doc_states"]} - outdir = HERE - rows, files = [], [] - total_primary = total_secondary = 0 - fill_sum = fill_n = 0 - - for d in A["doc_states"]: - for sel in A["selections"]: - svg, verbs, grouped = render_state(A, sel, d) - name = f'{d["id"]}__{sel["id"]}.svg' - with open(os.path.join(outdir, name), "w", encoding="utf-8") as f: - f.write(svg) - files.append((name, f'{sel["name"]} — {d["name"]}')) - total_primary += 1 - fill_sum += len(grouped) - fill_n += 1 - secondaries = [] - for sid, vs in grouped.items(): - if len(vs) > 1: - s2, _, _ = render_state(A, sel, d, secondary=sid) - n2 = f'{d["id"]}__{sel["id"]}__{sid}.svg' - with open(os.path.join(outdir, n2), "w", encoding="utf-8") as f: - f.write(s2) - label = next(s["label"] for s in A["slots"] if s["id"] == sid) - files.append((n2, f'{sel["name"]} — {label} ring')) - secondaries.append(sid) - total_secondary += 1 - rows.append({ - "doc": d["name"], "sel": sel["name"], "mode": sel["mode"], - "verbs": len(verbs), "slots": len(grouped), - "second": len(secondaries), - "detail": {sid: [v["name"] for v in vs] for sid, vs in grouped.items()}, - }) - - # Form-factor comparison: the SAME state as a ring and as a vertical list. - for sid in ("face_planar", "edge_str", "body_solid", "sk_line", "none"): - sel = next(s for s in A["selections"] if s["id"] == sid) - d = docs["fresh"] if sid == "none" else docs["rich"] - with open(os.path.join(outdir, f"list__{sid}.svg"), "w", encoding="utf-8") as f: - f.write(render_list_state(A, sel, d)) - for sid, fam in (("face_planar", "add"), ("sk_none", "create")): - sel = next(s for s in A["selections"] if s["id"] == sid) - with open(os.path.join(outdir, f"list__{sid}__{fam}.svg"), "w", encoding="utf-8") as f: - f.write(render_list_state(A, sel, docs["rich"], expand=fam)) - - # comparison sheet: 8 vs 12 slots on the same three selections - for cap in (8, 12): - for sid in ("face_planar", "edge_str", "sk_line"): - sel = next(s for s in A["selections"] if s["id"] == sid) - svg, _, _ = render_state(A, sel, docs["rich"], capacity=cap) - n = f'cmp_{cap}__{sid}.svg' - with open(os.path.join(outdir, n), "w", encoding="utf-8") as f: - f.write(svg) - - write_atlas(A, rows, files, total_primary, total_secondary, - fill_sum / max(1, fill_n)) - print(f"{total_primary} primary + {total_secondary} secondary = " - f"{total_primary+total_secondary} offer states rendered") - print(f"mean populated slots per primary ring: {fill_sum/max(1,fill_n):.2f} of 8") - if OVERFLOWS: - seen = {(f, tuple(v)) for _, _, f, v in OVERFLOWS} - print(f"OVERFLOW: {len(OVERFLOWS)} sub-rings did not fit 8 slots — " - f"{len(seen)} distinct case(s):") - for f, v in sorted(seen): - print(f" {f}: {', '.join(v)} pushed behind 'More'") - - -def write_atlas(A, rows, files, n_prim, n_sec, mean_fill): - gui_missing = [v["name"] for v in A["verbs"] if not v.get("gui", True)] - esc = lambda s: (s.replace("&", "&").replace("<", "<").replace(">", ">")) - cards = "".join( - f'
{esc(t)}
{esc(t)}
' - for n, t in files) - cmp8 = "".join(f'
' - f'
8 slots — {s}
' - for s in ("face_planar", "edge_str", "sk_line")) - cmp12 = "".join(f'
' - f'
12 slots — {s}
' - for s in ("face_planar", "edge_str", "sk_line")) - if OVERFLOWS: - cases = sorted({(f, tuple(v)) for _, _, f, v in OVERFLOWS}) - over_html = ("Measured, not predicted: " + "; ".join( - f'the {esc(f)} sub-ring needs {8 + len(v)} addresses, so ' - f'{esc(", ".join(v))} {"is" if len(v) == 1 else "are"} pushed behind a “More” slot' - for f, v in cases) + - ". This is the decision the ring size actually turns on — either a verb moves to " - "another family, or the tail goes to a third level, or the ring is not eight. " - "It affects sketch mode only; every model-mode family fits.") - else: - over_html = "No sub-ring exceeds the ring capacity. Eight slots is sufficient everywhere." - trs = "".join( - f'{esc(r["sel"])}{esc(r["doc"])}{r["verbs"]}' - f'{r["slots"]}/8{r["second"]}' - f'{esc(" · ".join(k + ": " + ", ".join(v) for k, v in r["detail"].items()))}' - for r in rows) - html = f"""Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
{len(A["verbs"])}verbs mapped
-
{len(A["selections"])}selection kinds
-
{n_prim}primary rings
-
{n_sec}secondary rings
-
{n_prim+n_sec}states total
-
{mean_fill:.1f}/8mean slots filled
-
{len(gui_missing)}verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
{cmp8}
-
{cmp12}
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - {trs} -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
- -

Overflow — the one place eight slots is not enough

-

{over_html}

- -

Not in the offer

-

{esc(", ".join(A["chrome_only"]["items"]))} — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - {esc(", ".join(gui_missing))}.

- -

All states

-
{cards}
-
-""" - with open(os.path.join(UX, "offer_atlas.html"), "w", encoding="utf-8") as f: - f.write(html) - - # A second, SELF-CONTAINED copy for review outside the repo: the artifact host blocks - # every external request, so relative would silently show nothing. Curated - # rather than all 113 states — the whole set inlined is 1.5 MB, which is a poor thing to - # send to the low-end machine this design is meant to serve (6.1). - def inline(name): - p = os.path.join(HERE, name) - if not os.path.exists(p): - return "" - s = open(p, encoding="utf-8").read() - return s.replace("{inline(n)}
{esc(t)}
' - for n, t in picks if inline(n)) - head, _, tail = html.partition('

All states

') - # The comparison grids in the head use , which resolves to nothing - # once the page is served on its own. Inline those too rather than shipping empty frames. - head = re.sub(r']*>', - lambda m: inline(m.group(1)), head) - inline_html = head + '

The states

\n
' + figs + '
\n' - with open(os.path.join(UX, "offer_atlas_inline.html"), "w", encoding="utf-8") as f: - f.write(inline_html) - - -if __name__ == "__main__": - main() diff --git a/docs/CAD/ux/mockups/list__body_solid.svg b/docs/CAD/ux/mockups/list__body_solid.svg deleted file mode 100644 index ec3b3a84f4..0000000000 --- a/docs/CAD/ux/mockups/list__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSOLID BODYCreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemove3Dress-up2Repeat3MoveShift+YReference3Modify3 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__edge_str.svg b/docs/CAD/ux/mockups/list__edge_str.svg deleted file mode 100644 index 3942000d25..0000000000 --- a/docs/CAD/ux/mockups/list__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSTRAIGHT EDGECreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-up2Pattern on CurveTransformTransform needs a body — add or import one firstReference3ModifyDelete Face needs a body — add or import one first \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__face_planar.svg b/docs/CAD/ux/mockups/list__face_planar.svg deleted file mode 100644 index 5ff6892902..0000000000 --- a/docs/CAD/ux/mockups/list__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__face_planar__add.svg b/docs/CAD/ux/mockups/list__face_planar__add.svg deleted file mode 100644 index fb80f2a5c7..0000000000 --- a/docs/CAD/ux/mockups/list__face_planar__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face — pick oneWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2ExtrudeShift+EThicken \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__none.svg b/docs/CAD/ux/mockups/list__none.svg deleted file mode 100644 index 1e68606383..0000000000 --- a/docs/CAD/ux/mockups/list__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESnothing yetRight-click the geometry to see what you can do with itFresh document · vertical listNOTHING SELECTEDSketchShift+SAdd materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-upPick an edge to roundRepeatCreate a solid body to pattern firstTransformTransform needs a body — add or import one firstReference4ModifyDelete Face needs a body — add or import one first \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__sk_line.svg b/docs/CAD/ux/mockups/list__sk_line.svg deleted file mode 100644 index 1b1c2e9cd2..0000000000 --- a/docs/CAD/ux/mockups/list__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSKETCH LINECreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2 \ No newline at end of file diff --git a/docs/CAD/ux/mockups/list__sk_none__create.svg b/docs/CAD/ux/mockups/list__sk_none__create.svg deleted file mode 100644 index 0b41268fa6..0000000000 --- a/docs/CAD/ux/mockups/list__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked — pick oneWorking document · vertical listSKETCH, NOTHING PICKEDCreate9Add materialRemoveDress-upRepeatTransformReference2ModifyLineLRectangleRCircleCArcASlotSEllipseESplineBPolygonGPointP \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__art.svg b/docs/CAD/ux/mockups/rich__art.svg deleted file mode 100644 index e835ed1ce0..0000000000 --- a/docs/CAD/ux/mockups/rich__art.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__art__modify.svg b/docs/CAD/ux/mockups/rich__art__modify.svg deleted file mode 100644 index 4c8cdef2b5..0000000000 --- a/docs/CAD/ux/mockups/rich__art__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsABCDeleteDelEditText / imported art · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__bodies_2.svg b/docs/CAD/ux/mockups/rich__bodies_2.svg deleted file mode 100644 index a977b7f1de..0000000000 --- a/docs/CAD/ux/mockups/rich__bodies_2.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__bodies_2__reference.svg b/docs/CAD/ux/mockups/rich__bodies_2__reference.svg deleted file mode 100644 index 1bfbac0db0..0000000000 --- a/docs/CAD/ux/mockups/rich__bodies_2__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureInterferenceTwo bodies · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_sheet.svg b/docs/CAD/ux/mockups/rich__body_sheet.svg deleted file mode 100644 index a1cc27808d..0000000000 --- a/docs/CAD/ux/mockups/rich__body_sheet.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_sheet__modify.svg b/docs/CAD/ux/mockups/rich__body_sheet__modify.svg deleted file mode 100644 index 7ce8dbee54..0000000000 --- a/docs/CAD/ux/mockups/rich__body_sheet__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSheet body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid.svg b/docs/CAD/ux/mockups/rich__body_solid.svg deleted file mode 100644 index e958532347..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__dressup.svg b/docs/CAD/ux/mockups/rich__body_solid__dressup.svg deleted file mode 100644 index 7a9ceed334..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferSolid body · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__modify.svg b/docs/CAD/ux/mockups/rich__body_solid__modify.svg deleted file mode 100644 index 7a6340d40f..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsColourDeleteDelEditSolid body · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__reference.svg b/docs/CAD/ux/mockups/rich__body_solid__reference.svg deleted file mode 100644 index 27639836c6..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMassProjectMeasureSolid body · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__remove.svg b/docs/CAD/ux/mockups/rich__body_solid__remove.svg deleted file mode 100644 index edbddb7115..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__body_solid__repeat.svg b/docs/CAD/ux/mockups/rich__body_solid__repeat.svg deleted file mode 100644 index 74dd67c7de..0000000000 --- a/docs/CAD/ux/mockups/rich__body_solid__repeat.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Repeat — pick oneWorking document · 8 slotsPatternShift+NMirrorShift+ZPattern on CurveSolid body · Repeat \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__coordsys.svg b/docs/CAD/ux/mockups/rich__coordsys.svg deleted file mode 100644 index 8cef106106..0000000000 --- a/docs/CAD/ux/mockups/rich__coordsys.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__coordsys__modify.svg b/docs/CAD/ux/mockups/rich__coordsys__modify.svg deleted file mode 100644 index 92eb28d3dc..0000000000 --- a/docs/CAD/ux/mockups/rich__coordsys__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditCoordinate system · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_axis.svg b/docs/CAD/ux/mockups/rich__datum_axis.svg deleted file mode 100644 index c9da648ab7..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_axis.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_axis__modify.svg b/docs/CAD/ux/mockups/rich__datum_axis__modify.svg deleted file mode 100644 index fd0ae80c52..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_axis__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum axis · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane.svg b/docs/CAD/ux/mockups/rich__datum_plane.svg deleted file mode 100644 index 8ef88bd9a3..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__modify.svg b/docs/CAD/ux/mockups/rich__datum_plane__modify.svg deleted file mode 100644 index 39e5cad41e..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditDatum plane · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__reference.svg b/docs/CAD/ux/mockups/rich__datum_plane__reference.svg deleted file mode 100644 index bae3119b6b..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsProjectPlaneShift+PHelixDatum plane · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__datum_plane__remove.svg b/docs/CAD/ux/mockups/rich__datum_plane__remove.svg deleted file mode 100644 index c98b33ad31..0000000000 --- a/docs/CAD/ux/mockups/rich__datum_plane__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HCutShift+XDatum plane · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_circ.svg b/docs/CAD/ux/mockups/rich__edge_circ.svg deleted file mode 100644 index 1d07291623..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_circ.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg b/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg deleted file mode 100644 index b315fc2e22..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_circ__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferCircular edge · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str.svg b/docs/CAD/ux/mockups/rich__edge_str.svg deleted file mode 100644 index 2c41ce74fc..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str__dressup.svg b/docs/CAD/ux/mockups/rich__edge_str__dressup.svg deleted file mode 100644 index 8e674c044f..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferStraight edge · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__edge_str__reference.svg b/docs/CAD/ux/mockups/rich__edge_str__reference.svg deleted file mode 100644 index bc99ca6a13..0000000000 --- a/docs/CAD/ux/mockups/rich__edge_str__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasurePlaneShift+PAxisShift+AStraight edge · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl.svg b/docs/CAD/ux/mockups/rich__face_cyl.svg deleted file mode 100644 index 3c2860373f..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl__modify.svg b/docs/CAD/ux/mockups/rich__face_cyl__modify.svg deleted file mode 100644 index 9f573682ad..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCylindrical face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_cyl__reference.svg b/docs/CAD/ux/mockups/rich__face_cyl__reference.svg deleted file mode 100644 index a62be81de8..0000000000 --- a/docs/CAD/ux/mockups/rich__face_cyl__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsMeasureAxisShift+AHelixCylindrical face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_other.svg b/docs/CAD/ux/mockups/rich__face_other.svg deleted file mode 100644 index e5cff4eee5..0000000000 --- a/docs/CAD/ux/mockups/rich__face_other.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_other__modify.svg b/docs/CAD/ux/mockups/rich__face_other__modify.svg deleted file mode 100644 index 8b5fcfd63f..0000000000 --- a/docs/CAD/ux/mockups/rich__face_other__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditCurved face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar.svg b/docs/CAD/ux/mockups/rich__face_planar.svg deleted file mode 100644 index 5a58e2fb72..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__add.svg b/docs/CAD/ux/mockups/rich__face_planar__add.svg deleted file mode 100644 index 82acc85038..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__dressup.svg b/docs/CAD/ux/mockups/rich__face_planar__dressup.svg deleted file mode 100644 index 8d32b9f212..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletShift+FChamferDraftShift+DPlanar face · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__modify.svg b/docs/CAD/ux/mockups/rich__face_planar__modify.svg deleted file mode 100644 index bffd218131..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDelete FaceEditPlanar face · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__reference.svg b/docs/CAD/ux/mockups/rich__face_planar__reference.svg deleted file mode 100644 index 4682f1e7b1..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__remove.svg b/docs/CAD/ux/mockups/rich__face_planar__remove.svg deleted file mode 100644 index b77a5a0c50..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__remove.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsHoleShift+HShellShift+KPlanar face · Remove \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__face_planar__transform.svg b/docs/CAD/ux/mockups/rich__face_planar__transform.svg deleted file mode 100644 index 2e27983c8b..0000000000 --- a/docs/CAD/ux/mockups/rich__face_planar__transform.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Transform — pick oneWorking document · 8 slotsMateAlign toPlanar face · Transform \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__none.svg b/docs/CAD/ux/mockups/rich__none.svg deleted file mode 100644 index 4e8a9dc640..0000000000 --- a/docs/CAD/ux/mockups/rich__none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__none__reference.svg b/docs/CAD/ux/mockups/rich__none__reference.svg deleted file mode 100644 index 14c47c4b27..0000000000 --- a/docs/CAD/ux/mockups/rich__none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CHelixPlaneShift+PAxisShift+ANothing selected · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent.svg b/docs/CAD/ux/mockups/rich__sk_2ent.svg deleted file mode 100644 index 738b01ecf2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__create.svg b/docs/CAD/ux/mockups/rich__sk_2ent__create.svg deleted file mode 100644 index 6d27ffa34a..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Two sketch entities · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg b/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg deleted file mode 100644 index 929520b8d2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHTwo sketch entities · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg b/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg deleted file mode 100644 index d8be7c2d4f..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXTwo sketch entities · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg b/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg deleted file mode 100644 index 9ffc2592a8..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_2ent__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKTwo sketch entities · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc.svg b/docs/CAD/ux/mockups/rich__sk_arc.svg deleted file mode 100644 index d470369f1a..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__create.svg b/docs/CAD/ux/mockups/rich__sk_arc__create.svg deleted file mode 100644 index 1f901596ec..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch arc or circle · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__modify.svg b/docs/CAD/ux/mockups/rich__sk_arc__modify.svg deleted file mode 100644 index 52f9d7d3e5..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch arc or circle · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_arc__reference.svg b/docs/CAD/ux/mockups/rich__sk_arc__reference.svg deleted file mode 100644 index 53e949c184..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_arc__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch arc or circle · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line.svg b/docs/CAD/ux/mockups/rich__sk_line.svg deleted file mode 100644 index 4ca4000d59..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__create.svg b/docs/CAD/ux/mockups/rich__sk_line__create.svg deleted file mode 100644 index c37f2d0e45..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch line · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__dressup.svg b/docs/CAD/ux/mockups/rich__sk_line__dressup.svg deleted file mode 100644 index 29e86762d2..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__dressup.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Dress-up — pick oneWorking document · 8 slotsFilletFChamferHSketch line · Dress-up \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__modify.svg b/docs/CAD/ux/mockups/rich__sk_line__modify.svg deleted file mode 100644 index b9775b7d94..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelExtendXSketch line · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_line__reference.svg b/docs/CAD/ux/mockups/rich__sk_line__reference.svg deleted file mode 100644 index 6eb1ef621f..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_line__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsConstructionQDimensionDConstrainKSketch line · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop.svg b/docs/CAD/ux/mockups/rich__sk_loop.svg deleted file mode 100644 index c07d1c09c3..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop__add.svg b/docs/CAD/ux/mockups/rich__sk_loop__add.svg deleted file mode 100644 index bf9f429b81..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop__add.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsSurface FillExtrudeShift+ERevolveShift+RSweepShift+WLoftShift+LSurface ExtrudeShift+GSurface RevolveSurface LoftClosed sketch loop · Add material \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_loop__modify.svg b/docs/CAD/ux/mockups/rich__sk_loop__modify.svg deleted file mode 100644 index c466379c9e..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_loop__modify.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Modify — pick oneWorking document · 8 slotsDeleteDelEditClosed sketch loop · Modify \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none.svg b/docs/CAD/ux/mockups/rich__sk_none.svg deleted file mode 100644 index ffe49ab9a0..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none__create.svg b/docs/CAD/ux/mockups/rich__sk_none__create.svg deleted file mode 100644 index c9a2bc698d..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_none__reference.svg b/docs/CAD/ux/mockups/rich__sk_none__reference.svg deleted file mode 100644 index cc9d465fa4..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_none__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstructionQSketch, nothing picked · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point.svg b/docs/CAD/ux/mockups/rich__sk_point.svg deleted file mode 100644 index f089787bca..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point__create.svg b/docs/CAD/ux/mockups/rich__sk_point__create.svg deleted file mode 100644 index 5d2070a6c5..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point__create.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch point · Create \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__sk_point__reference.svg b/docs/CAD/ux/mockups/rich__sk_point__reference.svg deleted file mode 100644 index e090382a24..0000000000 --- a/docs/CAD/ux/mockups/rich__sk_point__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsDimensionDConstrainKSketch point · Reference \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__vertex.svg b/docs/CAD/ux/mockups/rich__vertex.svg deleted file mode 100644 index f37bbd7d47..0000000000 --- a/docs/CAD/ux/mockups/rich__vertex.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex \ No newline at end of file diff --git a/docs/CAD/ux/mockups/rich__vertex__reference.svg b/docs/CAD/ux/mockups/rich__vertex__reference.svg deleted file mode 100644 index ceabba032e..0000000000 --- a/docs/CAD/ux/mockups/rich__vertex__reference.svg +++ /dev/null @@ -1 +0,0 @@ -PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CMeasurePlaneShift+PAxisShift+AVertex · Reference \ No newline at end of file diff --git a/docs/CAD/ux/offer_atlas.html b/docs/CAD/ux/offer_atlas.html deleted file mode 100644 index 35c4f5860c..0000000000 --- a/docs/CAD/ux/offer_atlas.html +++ /dev/null @@ -1,78 +0,0 @@ -Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
60verbs mapped
-
20selection kinds
-
40primary rings
-
73secondary rings
-
113states total
-
3.5/8mean slots filled
-
5verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
8 slots — face_planar
8 slots — edge_str
8 slots — sk_line
-
12 slots — face_planar
12 slots — edge_str
12 slots — sk_line
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
- -

Overflow — the one place eight slots is not enough

-

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

- -

Not in the offer

-

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - Split, Pattern on Curve, Align to, Measure, Interference.

- -

All states

-
Nothing selected — Working document
Nothing selected — Working document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Working document
Planar face — Working document
Planar face — Add material ring
Planar face — Add material ring
Planar face — Remove ring
Planar face — Remove ring
Planar face — Dress-up ring
Planar face — Dress-up ring
Planar face — Transform ring
Planar face — Transform ring
Planar face — Reference ring
Planar face — Reference ring
Planar face — Modify ring
Planar face — Modify ring
Cylindrical face — Working document
Cylindrical face — Working document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Cylindrical face — Modify ring
Cylindrical face — Modify ring
Curved face — Working document
Curved face — Working document
Curved face — Modify ring
Curved face — Modify ring
Straight edge — Working document
Straight edge — Working document
Straight edge — Dress-up ring
Straight edge — Dress-up ring
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Working document
Circular edge — Working document
Circular edge — Dress-up ring
Circular edge — Dress-up ring
Vertex — Working document
Vertex — Working document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Working document
Solid body — Working document
Solid body — Remove ring
Solid body — Remove ring
Solid body — Dress-up ring
Solid body — Dress-up ring
Solid body — Repeat ring
Solid body — Repeat ring
Solid body — Reference ring
Solid body — Reference ring
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Working document
Sheet body — Working document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Working document
Two bodies — Working document
Two bodies — Reference ring
Two bodies — Reference ring
Datum plane — Working document
Datum plane — Working document
Datum plane — Remove ring
Datum plane — Remove ring
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Working document
Datum axis — Working document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Working document
Coordinate system — Working document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Working document
Text / imported art — Working document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Working document
Closed sketch loop — Working document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Working document
Sketch, nothing picked — Working document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Working document
Sketch line — Working document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Working document
Sketch arc or circle — Working document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Working document
Sketch point — Working document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Working document
Two sketch entities — Working document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
Nothing selected — Fresh document
Nothing selected — Fresh document
Nothing selected — Reference ring
Nothing selected — Reference ring
Planar face — Fresh document
Planar face — Fresh document
Planar face — Reference ring
Planar face — Reference ring
Cylindrical face — Fresh document
Cylindrical face — Fresh document
Cylindrical face — Reference ring
Cylindrical face — Reference ring
Curved face — Fresh document
Curved face — Fresh document
Straight edge — Fresh document
Straight edge — Fresh document
Straight edge — Reference ring
Straight edge — Reference ring
Circular edge — Fresh document
Circular edge — Fresh document
Vertex — Fresh document
Vertex — Fresh document
Vertex — Reference ring
Vertex — Reference ring
Solid body — Fresh document
Solid body — Fresh document
Solid body — Modify ring
Solid body — Modify ring
Sheet body — Fresh document
Sheet body — Fresh document
Sheet body — Modify ring
Sheet body — Modify ring
Two bodies — Fresh document
Two bodies — Fresh document
Datum plane — Fresh document
Datum plane — Fresh document
Datum plane — Reference ring
Datum plane — Reference ring
Datum plane — Modify ring
Datum plane — Modify ring
Datum axis — Fresh document
Datum axis — Fresh document
Datum axis — Modify ring
Datum axis — Modify ring
Coordinate system — Fresh document
Coordinate system — Fresh document
Coordinate system — Modify ring
Coordinate system — Modify ring
Text / imported art — Fresh document
Text / imported art — Fresh document
Text / imported art — Modify ring
Text / imported art — Modify ring
Closed sketch loop — Fresh document
Closed sketch loop — Fresh document
Closed sketch loop — Add material ring
Closed sketch loop — Add material ring
Closed sketch loop — Modify ring
Closed sketch loop — Modify ring
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Fresh document
Sketch, nothing picked — Create ring
Sketch, nothing picked — Create ring
Sketch, nothing picked — Reference ring
Sketch, nothing picked — Reference ring
Sketch line — Fresh document
Sketch line — Fresh document
Sketch line — Create ring
Sketch line — Create ring
Sketch line — Dress-up ring
Sketch line — Dress-up ring
Sketch line — Reference ring
Sketch line — Reference ring
Sketch line — Modify ring
Sketch line — Modify ring
Sketch arc or circle — Fresh document
Sketch arc or circle — Fresh document
Sketch arc or circle — Create ring
Sketch arc or circle — Create ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Reference ring
Sketch arc or circle — Modify ring
Sketch arc or circle — Modify ring
Sketch point — Fresh document
Sketch point — Fresh document
Sketch point — Create ring
Sketch point — Create ring
Sketch point — Reference ring
Sketch point — Reference ring
Two sketch entities — Fresh document
Two sketch entities — Fresh document
Two sketch entities — Create ring
Two sketch entities — Create ring
Two sketch entities — Dress-up ring
Two sketch entities — Dress-up ring
Two sketch entities — Reference ring
Two sketch entities — Reference ring
Two sketch entities — Modify ring
Two sketch entities — Modify ring
-
diff --git a/docs/CAD/ux/offer_atlas_inline.html b/docs/CAD/ux/offer_atlas_inline.html deleted file mode 100644 index 3bbfb1b303..0000000000 --- a/docs/CAD/ux/offer_atlas_inline.html +++ /dev/null @@ -1,77 +0,0 @@ -Design tab — offer atlas - -
-

The offer — atlas of every state

-

Every state of the object-driven tool offer, generated from - docs/ux/tool_atlas.json. The invariant under test: a verb has one address, that - address is the same in every selection where it appears, and slots that do not apply are drawn - empty rather than compacted.

-
-
60verbs mapped
-
20selection kinds
-
40primary rings
-
73secondary rings
-
113states total
-
3.5/8mean slots filled
-
5verbs with no GUI yet
-
-
-
-

Decision 0 — ring or vertical list

-

The live question. Both forms carry the SAME map and the same invariant — fixed order, never - re-sorted, nothing compacted; only the geometry differs. Left-click selects; right-click opens the - offer. What the list buys: a disabled row can state its own reason in the words the product - already ships, where an empty slot in a ring is mute; nine sketch primitives fit without an - overflow; shortcuts line up in a readable column; long translated names fit; and it is navigable - by arrow key and by screen reader, which a radial is not. What it costs: no equidistant flick - gesture, and travel to the last row is longer than to the nearest direction. Pairs below — - list first, the same state as a ring second.

- -

Decision 1 — ring capacity

-

The same three selections at eight and at twelve. Eight keeps 45° between neighbours, which is - the reliable eyes-free pointing threshold and maps 1:1 to the numpad; twelve buys direct addresses - for more verbs at 30° spacing and positions that stop being nameable.

-
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
8 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sk_line
-
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — face_planar
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 12 slotsDress-up2Pattern on CurveReference3Straight edge
12 slots — edge_str
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sk_line
- -

Decision 2 — one map or one per mode

-

These renders use ONE shared map: sketch verbs occupy the same eight families as model verbs, - so dress-up is south-east whether you picked a solid edge or a sketch line. Compare the sketch-mode - states below against the model-mode ones — if a verb that exists in both modes ever appears at two - addresses, the shared map has failed and the split map is the answer.

- -

The matrix — every selection, every document state

-
- - -
SelectionDocumentVerbsSlots2nd ringsWhat lands where
Nothing selectedWorking document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceWorking document188/86create: Sketch · add: Extrude, Thicken · remove: Hole, Shell · dressup: Fillet, Chamfer, Draft · repeat: Pattern · transform: Mate, Align to · reference: Plane, Axis, Coord Sys, Project, Measure · modify: Edit, Delete Face
Cylindrical faceWorking document63/82remove: Thread · reference: Axis, Helix, Measure · modify: Edit, Delete Face
Curved faceWorking document54/81add: Thicken · dressup: Draft · reference: Measure · modify: Edit, Delete Face
Straight edgeWorking document63/82dressup: Fillet, Chamfer · repeat: Pattern on Curve · reference: Plane, Axis, Measure
Circular edgeWorking document43/81remove: Thread · dressup: Fillet, Chamfer · reference: Measure
VertexWorking document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyWorking document156/85remove: Shell, Cut, Split · dressup: Fillet, Chamfer · repeat: Pattern, Mirror, Pattern on Curve · transform: Move · reference: Project, Measure, Mass · modify: Edit, Colour, Delete
Sheet bodyWorking document75/81add: Thicken Surface · dressup: Surface Offset · transform: Move · reference: Measure · modify: Edit, Colour, Delete
Two bodiesWorking document54/81add: Combine · transform: Mate · reference: Measure, Interference · modify: Delete
Datum planeWorking document95/83create: Sketch · remove: Hole, Cut · repeat: Mirror · reference: Plane, Helix, Project · modify: Edit, Delete
Datum axisWorking document21/81modify: Edit, Delete
Coordinate systemWorking document32/81transform: Mate · modify: Edit, Delete
Text / imported artWorking document43/81repeat: Pattern · transform: Move · modify: Edit, Delete
Closed sketch loopWorking document113/82add: Extrude, Revolve, Sweep, Loft, Surface Extrude, Surface Revolve, Surface Loft, Surface Fill · repeat: Pattern · modify: Edit, Delete
Sketch, nothing pickedWorking document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleWorking document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointWorking document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesWorking document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Nothing selectedFresh document52/81create: Sketch · reference: Plane, Axis, Coord Sys, Helix
Planar faceFresh document74/81create: Sketch · add: Extrude · reference: Plane, Axis, Coord Sys, Measure · modify: Edit
Cylindrical faceFresh document42/81reference: Axis, Helix, Measure · modify: Edit
Curved faceFresh document22/80reference: Measure · modify: Edit
Straight edgeFresh document31/81reference: Plane, Axis, Measure
Circular edgeFresh document11/80reference: Measure
VertexFresh document41/81reference: Plane, Axis, Coord Sys, Measure
Solid bodyFresh document32/81reference: Measure · modify: Edit, Delete
Sheet bodyFresh document32/81reference: Measure · modify: Edit, Delete
Two bodiesFresh document22/80reference: Measure · modify: Delete
Datum planeFresh document53/82create: Sketch · reference: Plane, Helix · modify: Edit, Delete
Datum axisFresh document21/81modify: Edit, Delete
Coordinate systemFresh document21/81modify: Edit, Delete
Text / imported artFresh document21/81modify: Edit, Delete
Closed sketch loopFresh document72/82add: Extrude, Revolve, Surface Extrude, Surface Revolve, Surface Fill · modify: Edit, Delete
Sketch, nothing pickedFresh document112/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · reference: Dimension, Construction
Sketch lineFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch arc or circleFresh document187/83create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
Sketch pointFresh document134/82create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · transform: Move · reference: Dimension, Constrain · modify: Delete
Two sketch entitiesFresh document208/84create: Line, Rectangle, Circle, Arc, Slot, Ellipse, Spline, Polygon, Point · add: Offset · remove: Trim · dressup: Fillet, Chamfer · repeat: Mirror · transform: Move · reference: Dimension, Constrain, Construction · modify: Extend, Delete
- -

Overflow — the one place eight slots is not enough

-

Measured, not predicted: the create sub-ring needs 10 addresses, so Polygon, Point are pushed behind a “More” slot. This is the decision the ring size actually turns on — either a verb moves to another family, or the tail goes to a third level, or the ring is not eight. It affects sketch mode only; every model-mode family fits.

- -

Not in the offer

-

Import STEP, Import mesh, Text, SVG, Export STEP, Commit to Plate, Undo, Redo, Variables, Section view, Origin planes, World axes — these act on the document, not on a selection, - so they stay in chrome. Verbs with kernel support but no GUI today, which still hold an address: - Split, Pattern on Curve, Align to, Measure, Interference.

- -

The states

-
PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected
Fresh document, nothing selected — the first-run picture
PreparePreviewDesignFEATURESnothing yetRight-click the geometry to see what you can do with itFresh document · vertical listNOTHING SELECTEDSketchShift+SAdd materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-upPick an edge to roundRepeatCreate a solid body to pattern firstTransformTransform needs a body — add or import one firstReference4ModifyDelete Face needs a body — add or import one first
LIST · fresh document — every family present, the unavailable ones say why
PreparePreviewDesignFEATURESnothing yetClick a face or a reference plane, then a toolFresh document · 8 slotsSketchShift+SReference4Nothing selected
RING · the same state — an empty slot cannot say anything
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2
LIST · planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
RING · planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked — pick oneWorking document · vertical listSKETCH, NOTHING PICKEDCreate9Add materialRemoveDress-upRepeatTransformReference2ModifyLineLRectangleRCircleCArcASlotSEllipseESplineBPolygonGPointP
LIST · sketch Create submenu — all 9 primitives fit, no overflow
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create
RING · the same submenu — 2 verbs pushed behind “More”
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face — pick oneWorking document · vertical listPLANAR FACESketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2ExtrudeShift+EThicken
LIST · planar face, Add material submenu
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material
RING · planar face, Add material sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSOLID BODYCreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemove3Dress-up2Repeat3MoveShift+YReference3Modify3
LIST · solid body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSTRAIGHT EDGECreateClick a face or a reference plane in the viewport, t…Add materialCreate a sketch, or pick a solid face, firstRemovePick a face or a plane to drill intoDress-up2Pattern on CurveTransformTransform needs a body — add or import one firstReference3ModifyDelete Face needs a body — add or import one first
LIST · straight edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Right-click the geometry to see what you can do with itWorking document · vertical listSKETCH LINECreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2
LIST · sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Click a face or a reference plane, then a toolWorking document · 8 slotsSketchShift+SReference4Nothing selected
RING · Nothing selected
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
RING · Planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Cylindrical face selected — pick what to do with itWorking document · 8 slotsThreadShift+TReference3Modify2Cylindrical face
RING · Cylindrical face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Curved face selected — pick what to do with itWorking document · 8 slotsThickenDraftShift+DMeasureModify2Curved face
RING · Curved face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Straight edge selected — pick what to do with itWorking document · 8 slotsDress-up2Pattern on CurveReference3Straight edge
RING · Straight edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Circular edge selected — pick what to do with itWorking document · 8 slotsThreadShift+TDress-up2MeasureCircular edge
RING · Circular edge
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Vertex selected — pick what to do with itWorking document · 8 slotsReference4Vertex
RING · Vertex
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Solid body selected — pick what to do with itWorking document · 8 slotsRemove3Dress-up2Repeat3MoveShift+YReference3Modify3Solid body
RING · Solid body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sheet body selected — pick what to do with itWorking document · 8 slotsThicken SurfaceSurface OffsetMoveShift+YMeasureModify3Sheet body
RING · Sheet body
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two bodies selected — pick what to do with itWorking document · 8 slotsCombineShift+BMateReference2DeleteDelTwo bodies
RING · Two bodies
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum plane selected — pick what to do with itWorking document · 8 slotsSketchShift+SRemove2MirrorShift+ZReference3Modify2Datum plane
RING · Datum plane
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Datum axis selected — pick what to do with itWorking document · 8 slotsModify2Datum axis
RING · Datum axis
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Coordinate system selected — pick what to do with itWorking document · 8 slotsMateModify2Coordinate system
RING · Coordinate system
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Text / imported art selected — pick what to do with itWorking document · 8 slotsABCPatternShift+NMoveShift+YModify2Text / imported art
RING · Text / imported art
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Closed sketch loop selected — pick what to do with itWorking document · 8 slotsAdd material8PatternShift+NModify2Closed sketch loop
RING · Closed sketch loop
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch, nothing picked selected — pick what to do with itWorking document · 8 slotsCreate9Reference2Sketch, nothing picked
RING · Sketch, nothing picked
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
RING · Sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch arc or circle selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTMirrorMMoveReference3Modify2Sketch arc or circle
RING · Sketch arc or circle
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch point selected — pick what to do with itWorking document · 8 slotsCreate9MoveReference2DeleteDelSketch point
RING · Sketch point
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Two sketch entities selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Two sketch entities
RING · Two sketch entities
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Add material — pick oneWorking document · 8 slotsExtrudeShift+EThickenPlanar face · Add material
Planar face · Add material sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Reference — pick oneWorking document · 8 slotsCoord SysShift+CProjectMeasurePlaneShift+PAxisShift+APlanar face · Reference
Planar face · Reference sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Create — pick oneWorking document · 8 slotsLineLRectangleRCircleCArcASlotSEllipseESplineBMore2Sketch, nothing picked · Create
Sketch · Create sub-ring (the overflow case)
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Remove — pick oneWorking document · 8 slotsShellShift+KCutShift+XSplitSolid body · Remove
Solid body · Remove sub-ring
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 8 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
8 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Planar face selected — pick what to do with itWorking document · 12 slotsSketchShift+SAdd material2Remove2Dress-up3PatternShift+NTransform2Reference5Modify2Planar face
12 slots — planar face
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 8 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
8 slots — sketch line
PreparePreviewDesignFEATURESSketch1Extrude1Hole1Fillet1Sketch2Extrude2Sketch line selected — pick what to do with itWorking document · 12 slotsCreate9OffsetOTrimTDress-up2MirrorMMoveReference3Modify2Sketch line
12 slots — sketch line
diff --git a/docs/HLSD/design-tab.md b/docs/HLSD/design-tab.md new file mode 100644 index 0000000000..67589be328 --- /dev/null +++ b/docs/HLSD/design-tab.md @@ -0,0 +1,213 @@ +# Design tab — High Level Design + +## Purpose and scope + +The Design tab is a parametric CAD environment inside the slicer: sketch, constrain, build +solid features, commit the result to the plate. It exists because the alternative is a round +trip through an external CAD application, and that round trip discards design intent at both +ends — a part edited after slicing comes back as a mesh rather than as the feature history +that produced it. Keeping the model in the project means a dimension can be changed after the +part has been sliced, with the nozzle diameter, the build volume and the material already +known. + +Its coupling to the rest of the application is deliberately narrow. It adds no stage to the +slicing pipeline and touches neither the preset system nor `Tab`. It reaches the rest of Orca +in two places: **Commit to Plate**, which hands finished solids to Prepare as ordinary model +objects, and one optional 3MF archive entry that carries the recipe. Everything else is +contained in `src/libslic3r/CAD/` and `src/slic3r/GUI/CAD/`. + +The user-facing manual lives in the wiki +([Design Tab](https://www.orcaslicer.com/wiki/design_tab)), not here. This document covers the +parts of the design that the code does not make evident. + +## The model is a recipe + +`CadDocument` holds an ordered list of `CadFeature` and nothing else that matters. Bodies, +meshes and display geometry are **derived**: `recompute()` replays the feature list from the +start and rebuilds them. Editing a dimension set twenty features ago is therefore an ordinary +edit — everything downstream is rebuilt by the same replay that built it the first time. + +Two consequences follow from deriving rather than storing: + +- **Undo is a snapshot of `features` alone.** The caller calls `checkpoint()` before the + mutations that make up one user action; undo restores that snapshot and recomputes. Because + everything else is derived, one checkpoint is exactly one `Ctrl+Z` step and the restored + state is exact rather than approximately reconstructed. The tab keeps this stack itself; it + is not Orca's project snapshot system, which operates on `Model` objects the Design tab does + not own until Commit. +- **Face and edge ids are session-scoped.** They are indices into `TopExp::MapShapes`, so a + rebuild invalidates every one of them. `CadDocument::topo_generation` is bumped on every + rebuild so a holder of an id can discover that it is stale instead of silently addressing a + different edge. The counter is deliberately not serialized: an id means nothing outside the + run that produced it. + +## Geometry kernel and dependency surface + +The kernel is OCCT, which OrcaSlicer **already** links — `Format/STEP.cpp`, `Format/svg.cpp` +and `Shape/TextShape.cpp` use it upstream. The Design tab adds no third-party dependency; it +widens the existing OCCT build by one module flag in `deps/OCCT/OCCT.cmake`: + +```cmake +-DBUILD_MODULE_ModelingAlgorithms=${SLIC3R_CAD} +``` + +Most of that module's twelve toolkits were already being built, because `DataExchange` — the +STEP path upstream ships — depends on them. The delta is `TKFillet` (used through +`BRepFilletAPI`), `TKOffset` (`BRepOffsetAPI`) and `TKFeat`, which nothing here references but +which the module flag builds anyway, because OCCT's module flags are all-or-nothing. On macOS +and Linux OCCT links statically, so an unreferenced toolkit costs build time and no shipped +bytes; on Windows OCCT builds shared, so the cost there is real DLL bytes. That Windows figure +has not been measured, and `OCCT.cmake` says so rather than carrying a number that was derived +from an incomplete toolkit list. + +On Windows the packaging step asserts that every linked OCCT toolkit has a shipped DLL and +fails the configure with the name of any that is missing, because the alternative failure — a +deps prefix built with a different `SLIC3R_CAD` setting than the app — otherwise surfaces as a +missing DLL at first launch. + +## The sketch constraint solver + +`src/libslic3r/slvs/` is a vendored subset of SolveSpace's `libslvs`: self-contained, no +external dependencies, **GPL-3.0**, with its `LICENSE` preserved verbatim in the directory. +`SketchSolver.cpp` is its only consumer and drives every sketch constraint in the tab. + +OrcaSlicer is AGPL-3.0. GPLv3 §13 permits combining a GPLv3 work with an AGPLv3 work and +AGPLv3 §13 grants the converse, so the combined work is distributable under AGPL-3.0 with the +solver's GPLv3 terms preserved. The solver is vendored rather than fetched as a dependency +because it is a pinned subset with no build system of its own; the cost of that choice is +upstream-sync burden, paid deliberately to keep `deps/` unchanged. + +## The SLIC3R_CAD gate + +`SLIC3R_CAD` (default ON) compiles the tab and selects the OCCT module flag above. With it OFF +the tab is not built and the deps prefix matches upstream exactly. The gate is cheap because +the hooks the Design tab adds to shared GUI code — chiefly the `m_design_sketch_tool` member +and the render, mouse and key hooks in `GLCanvas3D` — are null-guarded on the path they extend, +so removing the tab removes behaviour rather than requiring the host code to be rewritten. + +The flag has to agree between the dependencies and the application; that is what the DLL +assertion above is checking. + +## Project persistence + +A project stores the recipe as one optional archive entry, `Metadata/orca_cad.bin`, backed by +a single `std::string cad_recipe` on `Model`. The entry is written only when the string is +non-empty, and readers that do not know it ignore it, so projects that contain no CAD model are +byte-identical to what upstream would have written and older readers are unaffected. + +The blob is a cereal binary archive whose layout is the field order of `CadFeature`'s +save/load. That makes the format the one irreversible decision in the subsystem, and the rules +that keep it survivable are: + +- **Append only, never reorder.** Enums serialize positionally as their underlying integer, so + inserting a value in the middle of `SketchConstraintType` or `CadFeatureType` reinterprets + every constraint in every saved project. New fields go at the end. +- **Features are length-framed.** Since v5 each feature is a length-prefixed, self-contained + cereal stream, so a reader can skip a feature written by a newer build and stop cleanly on an + older one. This is what makes appending a field a non-breaking change from here on. v4 and + earlier still open through the pre-framing flat path; v1 is deliberately not loadable and has + no migration path. +- **A newer stamp is refused, not guessed at.** `deserialize_recipe` rejects a blob whose + version exceeds `ORCA_CAD_RECIPE_VERSION` with a message naming both versions. +- **The rules are held by fixtures, not by discipline.** `tests/data/cad_recipe_v{3,4,5}.bin` + are checked-in blobs from the builds that wrote them, and the tests that load them fail if a + field is reordered — which the in-memory round-trip test cannot detect. A regeneration test + (`[.regen]`, not run by default) produces a fresh fixture when a new version is stamped. + +`Import` features embed the imported solid as an OCCT BRep string inside the recipe rather than +referencing the source file, so a project opens without the STEP or mesh it was built from. +The cost is that saved projects are coupled to an OCCT BRep revision. + +## The interaction contract + +Three inputs carry the whole modelling loop — left click, right click and `Esc` — and the +contract between them is stated in code rather than spread across handlers. + +`DesignInteraction.hpp` defines a four-level LIFO stack whose enum value *is* the depth, so +"which level does this press belong to" is a comparison: + +| Level | Holds | One `Esc` press | +| --- | --- | --- | +| `Transient` | a value field or a popup menu | closes it; the tool stays armed | +| `Gesture` | an uncommitted delta — an entity being drawn, a body being dragged | reverts it; committed work is untouched | +| `Tool` | a feature card, an armed sketch tool, a constrain session | exits it; drawn entities survive | +| `Idle` | nothing transient | clears the selection; leaves a sketch session only if it is empty | + +`cad_escape_level()` is a `constexpr` free function over a POD of four booleans rather than a +method on the panel, so the ordering that is the entire contract is checkable without a window, +a GL context or an event loop — five `static_assert`s in the header do exactly that at compile +time. + +**The strict invariant: no level of `Esc` deletes a feature, discards a sketch that holds +geometry, or rolls history back.** Destroying work needs a gesture that says so — `Del` on an +explicit selection, the sketch ribbon's Cancel, which asks first, or `Ctrl+Z`. A sketch +*session* is deliberately not a `Tool` level; it is the environment the `Idle` level lives in, +which makes the destructive path unrepresentable rather than merely unlikely. + +Right-click is read at button-up against two independent budgets — 3 px of drift and 200 ms — +because drift alone still popped a menu at the end of a slow, careful orbit. The raycast uses +the press position, not the release. An armed sketch tool that already consumed the right +button (to terminate a chain, say) declines to also open a menu, through a read-and-clear flag. +Past either budget the event is navigation, and navigation does not transition the state +machine. + +Entering a sketch changes three things at once so the mode is legible: a banner above the +canvas (a sibling of the canvas, not a child over it — on GTK a child window over a +`wxGLCanvas` is a native window and does not reliably stack over GL), the printer bed muted so +a plate grid is never read as a sketch grid, and `N` to look normal to the plane. Code that +changes any of the three belongs with a change to this section. + +## The offer is generated, not hand-written + +Right-clicking geometry opens the *offer*: eight families in a fixed order, each verb at a +permanent row index, verbs that do not apply shown disabled **in place with their reason** +rather than removed. The invariant is that a verb's row index is identical in every selection +where it appears and that adding a verb never moves an existing one — the hand learns the +position, so the menu is never re-sorted, compacted or adaptively ordered. + +An invariant across 92 verbs and 20 selection kinds does not survive by review, so the map +exists once, as data: `scripts/CAD/tool_atlas.json` carries every verb with its row, key, icon, +accepted selections, preconditions and refusal string, and `scripts/CAD/gen_offer_table.py` +emits `src/slic3r/GUI/CAD/DesignOffer.hpp` from it. The header is checked in and never +hand-edited; `scripts/CAD/run-all-checks.sh` runs the generator with `--check` as its first +rung, which is what makes "GENERATED — DO NOT EDIT" a fact rather than a request. The generator +also refuses an atlas with a duplicate verb id, since `mcp_run_verb` resolves a verb by id and +would make the second one unreachable. + +The atlas and its generator sit in `scripts/CAD/` rather than in `docs/`: they are build inputs +for a checked-in header, not documentation. + +## Automation surface + +`McpControl` exposes the document over JSON-RPC when `ORCA_CAD_MCP` is set in the environment, +with `tools/orca_cad_mcp_bridge.py` as the client side. It describes the scene, queries +topology, measures, and runs the same verbs the offer does — it re-implements nothing, so a +scripted action and a clicked one cannot diverge. It is off unless the variable is set. + +## Where the code lives + +| Path | Role | +| --- | --- | +| `src/libslic3r/CAD/CadDocument.*` | the feature recipe, its replay, undo and serialization | +| `src/libslic3r/CAD/GeometryEngine.*` | OCCT wrapper — faces, edges, booleans, healing | +| `src/libslic3r/CAD/SketchEngine.*` | profile → wire → solid | +| `src/libslic3r/CAD/SketchSolver.*` | constraint solving, over the vendored solver | +| `src/libslic3r/slvs/` | vendored 2D constraint solver (GPLv3) | +| `src/slic3r/GUI/CAD/DesignPanel.*` | the tab: toolbar, feature cards, tree, key maps | +| `src/slic3r/GUI/CAD/DesignCanvas.*` | viewport integration | +| `src/slic3r/GUI/CAD/DesignSketchTool.*` | in-canvas sketching | +| `src/slic3r/GUI/CAD/DesignInteraction.hpp` | the Esc level contract | +| `src/slic3r/GUI/CAD/DesignOffer.hpp` | generated offer table | +| `scripts/CAD/tool_atlas.json` | source of truth for the offer | + +## Verification + +The kernel is covered by Catch2 suites in `tests/libslic3r/` (`test_caddocument`, +`test_sketchconstraints`, `test_sketchedit`, `test_sketchimport`, `test_sketchinference`, +`test_sketchprofile`, `test_slvs_constraints`), which need no display; +`scripts/CAD/run-kernel-tests.sh` builds only `libslic3r_tests` and runs them headless. + +The GUI half is not covered by CI, which has no OpenGL canvas or synthetic input: the ladders +in `scripts/CAD/` drive a running application in a local rig instead, and +`scripts/CAD/run-all-checks.sh` is the gate that runs all of them. A green kernel run says +nothing about the viewport, so the two are reported separately rather than as one number. diff --git a/scripts/CAD/README.md b/scripts/CAD/README.md index 861b77a976..a5c6836e29 100644 --- a/scripts/CAD/README.md +++ b/scripts/CAD/README.md @@ -33,6 +33,21 @@ part of `libslic3r_tests` and run under `ctest` on every platform like any other unit test. This script exists for the local loop, where it is a two-minute round trip instead of a full application build. +## Generated sources + +Two checked-in files are emitted from data that lives here, so the source and the thing +compiled against it cannot drift apart: + +| Generator | Source | Output | +|---|---|---| +| `gen_offer_table.py` | `tool_atlas.json` — every offer verb with its row, key, icon, accepted selections and refusal string | `src/slic3r/GUI/CAD/DesignOffer.hpp` | +| `mate-glyph/emit_glyph_table.py` | `mate-glyph/bear_outline.json`, measured off `mate-glyph/bear.step` by `extract_outline.py` (needs FreeCAD) | the `kBear…` tables in `DesignSketchTool.cpp` | + +`python3 scripts/CAD/gen_offer_table.py` rewrites the header and `--check` proves the +checked-in one matches the atlas — `run-all-checks.sh` runs the check as its first rung, +which is what makes the header's "GENERATED — DO NOT EDIT" enforceable. Edit the atlas, +never the header. + ## Build and run | Script | Purpose | @@ -48,6 +63,6 @@ Two constraints that are not obvious and have each cost a session: - **A window manager is required.** Without one, windows are never focused, and an unfocused GTK app ignores synthetic keys — which looks exactly like a code bug. -`docs/rig_build_traps.md` documents these and three more, with symptoms and exact +`scripts/CAD/rig_build_traps.md` documents these and three more, with symptoms and exact recovery commands. Read it before debugging a configure or link failure one of these scripts reports. diff --git a/scripts/CAD/build-gui-incremental.sh b/scripts/CAD/build-gui-incremental.sh index 539a21c973..f87113fdaf 100755 --- a/scripts/CAD/build-gui-incremental.sh +++ b/scripts/CAD/build-gui-incremental.sh @@ -15,7 +15,7 @@ # On success the binary is inside the persistent volume at # /OrcaSlicer/build/package/bin/orca-slicer (copy it out with a follow-up # `docker run --rm -v orcacad_buildcache:/b alpine cp ...` or via this script's tail). -# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md +# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): scripts/CAD/rig_build_traps.md set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" diff --git a/scripts/CAD/build-gui.sh b/scripts/CAD/build-gui.sh index 0a1a86dd5c..edf93a5ca0 100755 --- a/scripts/CAD/build-gui.sh +++ b/scripts/CAD/build-gui.sh @@ -5,7 +5,7 @@ # NEVER build inside the GUI container (snapmaker-gui / orcacad-gui). Its baked /OrcaSlicer tree # is the Jun-13 Snapmaker-derived source, so a `cmake .` in there silently reconfigures the # shared build dir as project(Snapmaker_Orca) and this fork's targets vanish. That is Trap 1 of -# five; all of them, with symptoms and exact recovery commands, are in docs/rig_build_traps.md. +# five; all of them, with symptoms and exact recovery commands, are in scripts/CAD/rig_build_traps.md. # Read that file before debugging a configure or link failure this script reports. # # Usage: @@ -92,7 +92,7 @@ docker run --rm \ # A target-only build writes src/Release/, but this fork's start-headless-gui.sh may default BIN to the # PACKAGED path that only build_linux.sh refreshes — launching with the default would then run a -# stale binary. Pass BIN explicitly. See docs/rig_build_traps.md. +# stale binary. Pass BIN explicitly. See scripts/CAD/rig_build_traps.md. echo "=== launch the rig on the binary just built ===" echo " docker exec -e BIN=/OrcaSlicer/build/src/Release/$BIN ${PREFIX}-gui /OrcaSlicer/scripts/CAD/start-headless-gui.sh" exit "$rc" diff --git a/docs/CAD/ux/mockups/gen_offer_table.py b/scripts/CAD/gen_offer_table.py similarity index 80% rename from docs/CAD/ux/mockups/gen_offer_table.py rename to scripts/CAD/gen_offer_table.py index 9744f9288b..442be27697 100644 --- a/docs/CAD/ux/mockups/gen_offer_table.py +++ b/scripts/CAD/gen_offer_table.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 -"""Emit the C++ offer table from docs/ux/tool_atlas.json. +"""Emit the C++ offer table from scripts/CAD/tool_atlas.json. - python3 docs/ux/mockups/gen_offer_table.py + python3 scripts/CAD/gen_offer_table.py # rewrite the header + python3 scripts/CAD/gen_offer_table.py --check # verify the checked-in header -The map exists ONCE. The mockups and the shipping menu read the same rows in the same -order from the same file, so a drawing and the product cannot drift apart — which is the -only way row constancy (charter 4.1) survives contact with a codebase. +The map exists ONCE: the atlas is the only place a verb's row, key, icon and refusal +string are written down, so the menu the user sees cannot drift from the table the code +is compiled against. Output: src/slic3r/GUI/CAD/DesignOffer.hpp, checked in and never hand-edited. """ @@ -14,15 +15,9 @@ import json import os import sys -HERE = os.path.dirname(os.path.abspath(__file__)) -UX = os.path.dirname(HERE) -# One dirname more than you would expect: this generator lives at docs/CAD/ux/mockups/, -# not docs/ux/mockups/, since the design docs moved into the CAD subfolder (bbd1989e1e). -# With the old count REPO resolved to docs/, so OUT pointed at docs/src/.../DesignOffer.hpp, -# which does not exist -- and --check then diffed the real generated table against an empty -# file and reported the whole 189-line header as a difference. -REPO = os.path.dirname(os.path.dirname(os.path.dirname(UX))) -ATLAS = os.path.join(UX, "tool_atlas.json") +HERE = os.path.dirname(os.path.abspath(__file__)) # scripts/CAD +REPO = os.path.dirname(os.path.dirname(HERE)) +ATLAS = os.path.join(HERE, "tool_atlas.json") OUT = os.path.join(REPO, "src", "slic3r", "GUI", "CAD", "DesignOffer.hpp") # selection id -> C++ enumerator @@ -42,15 +37,40 @@ def cstr(s): return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"' +def validate(A): + """Refuse an atlas the header cannot represent, naming every fault at once. + + An unknown slot or selection would surface as a bare ValueError from .index() below, and a + duplicate verb id would not surface at all: DesignPanel::mcp_run_verb looks a verb up by id + and takes the first match, so the second row would be unreachable from the offer. + """ + slot_ids = {s["id"] for s in A["slots"]} + sel_ids = {s["id"] for s in A["selections"]} + errs, seen = [], set() + for v in A["verbs"]: + if v["slot"] not in slot_ids: + errs.append(f'{v["id"]}: unknown slot {v["slot"]!r}') + for a in v["accepts"]: + if a not in sel_ids: + errs.append(f'{v["id"]}: accepts unknown selection {a!r}') + if v["id"] in seen: + errs.append(f'{v["id"]}: duplicate verb id') + seen.add(v["id"]) + for s in sel_ids - set(ENUM): + errs.append(f"selection {s!r} has no OfferSel enumerator") + if errs: + sys.exit("tool_atlas.json is inconsistent:\n " + "\n ".join(errs)) + + def main(): A = json.load(open(ATLAS, encoding="utf-8")) + validate(A) sels = [s["id"] for s in A["selections"]] - assert all(s in ENUM for s in sels), [s for s in sels if s not in ENUM] slots = [s["id"] for s in A["slots"]] lines = [ "// GENERATED FILE — DO NOT EDIT.", - "// Source: docs/ux/tool_atlas.json Generator: docs/ux/mockups/gen_offer_table.py", + "// Source: scripts/CAD/tool_atlas.json Generator: scripts/CAD/gen_offer_table.py", "//", "// The object-driven tool offer (charter 4.1): every verb has ONE row index, that index", "// is the same in every selection it appears in, and verbs that do not apply are shown", diff --git a/docs/CAD/design/mate-connectors/bear.step b/scripts/CAD/mate-glyph/bear.step similarity index 100% rename from docs/CAD/design/mate-connectors/bear.step rename to scripts/CAD/mate-glyph/bear.step diff --git a/docs/CAD/design/mate-connectors/bear_outline.json b/scripts/CAD/mate-glyph/bear_outline.json similarity index 100% rename from docs/CAD/design/mate-connectors/bear_outline.json rename to scripts/CAD/mate-glyph/bear_outline.json diff --git a/docs/CAD/design/mate-connectors/emit_glyph_table.py b/scripts/CAD/mate-glyph/emit_glyph_table.py similarity index 100% rename from docs/CAD/design/mate-connectors/emit_glyph_table.py rename to scripts/CAD/mate-glyph/emit_glyph_table.py diff --git a/docs/CAD/design/mate-connectors/extract_outline.py b/scripts/CAD/mate-glyph/extract_outline.py similarity index 100% rename from docs/CAD/design/mate-connectors/extract_outline.py rename to scripts/CAD/mate-glyph/extract_outline.py diff --git a/docs/CAD/rig_build_traps.md b/scripts/CAD/rig_build_traps.md similarity index 100% rename from docs/CAD/rig_build_traps.md rename to scripts/CAD/rig_build_traps.md diff --git a/scripts/CAD/run-all-checks.sh b/scripts/CAD/run-all-checks.sh index 1c0388ac89..8a99a3b6cb 100755 --- a/scripts/CAD/run-all-checks.sh +++ b/scripts/CAD/run-all-checks.sh @@ -54,10 +54,9 @@ run_in_rig() { # copy the script in fresh, then run it ther # says. The header calls itself GENERATED and had been hand-edited anyway — which cost four rows # that existed only in the header, one row wired to the wrong action, and a count of 91 for a # 92-row array, so the last verb was unreachable (z8rs, ziam). -# docs/CAD/, not docs/: SoftFever moved the design docs into the CAD subfolder -# (bbd1989e1e) and this line kept the old path, so the rung failed on a missing file -# rather than on anything about the table. The other fork still has docs/ux/. -step "offer table matches the atlas" python3 docs/CAD/ux/mockups/gen_offer_table.py --check +# The atlas and its generator live beside this script, in scripts/CAD/: they are build inputs +# for a checked-in header, not documentation, so they do not belong under docs/. +step "offer table matches the atlas" python3 scripts/CAD/gen_offer_table.py --check step "kernel suite" scripts/CAD/run-kernel-tests.sh --vol "${KVOL:-orcacad_kerneltest}" diff --git a/scripts/CAD/run-kernel-tests.sh b/scripts/CAD/run-kernel-tests.sh index ef4356cb65..cc52a2a00b 100755 --- a/scripts/CAD/run-kernel-tests.sh +++ b/scripts/CAD/run-kernel-tests.sh @@ -19,7 +19,7 @@ # working tree to a per-volume staging dir on that host and re-runs this same script # there, so the verification contract is identical either way. Drop --host once the image # is present locally. -# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): docs/rig_build_traps.md +# Rig build traps already paid for once each (stale project, NLopt cache, pybind11, OCCT_LIBS, SLIC3R_CAD gate): scripts/CAD/rig_build_traps.md set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" diff --git a/docs/CAD/ux/tool_atlas.json b/scripts/CAD/tool_atlas.json similarity index 99% rename from docs/CAD/ux/tool_atlas.json rename to scripts/CAD/tool_atlas.json index 94709f2057..224b118c9e 100644 --- a/docs/CAD/ux/tool_atlas.json +++ b/scripts/CAD/tool_atlas.json @@ -1,6 +1,6 @@ { "_comment": [ - "Source of truth for the object-driven tool offer (see docs/cad_ux_guidelines.md 4.1).", + "Source of truth for the object-driven tool offer (see docs/HLSD/design-tab.md).", "Every verb, the selections it accepts, the document state it needs, and its fixed", "compass address. Extracted from the code, not from memory:", " verbs + shortcuts + refusal messages -> src/slic3r/GUI/CAD/DesignPanel.cpp (feat_dropdown", @@ -8,8 +8,8 @@ " kernel coverage -> src/libslic3r/CAD/CadDocument.hpp (enum CadFeatureType)", " headless coverage -> src/slic3r/GUI/CAD/McpControl.cpp (method == \"...\")", " selection kinds -> src/slic3r/GUI/CAD/DesignCanvas.hpp (the on_*_selected callbacks)", - "gen_offer_mockups.py reads this file; the eventual C++ offer table is generated from it", - "too, so the map exists once." + "gen_offer_table.py emits src/slic3r/GUI/CAD/DesignOffer.hpp from this file, so the map", + "exists once. Edit the atlas and regenerate; never hand-edit the header." ], "slots": [ { diff --git a/src/slic3r/GUI/CAD/DesignOffer.hpp b/src/slic3r/GUI/CAD/DesignOffer.hpp index ad1998d5c5..fd15f537d3 100644 --- a/src/slic3r/GUI/CAD/DesignOffer.hpp +++ b/src/slic3r/GUI/CAD/DesignOffer.hpp @@ -1,5 +1,5 @@ // GENERATED FILE — DO NOT EDIT. -// Source: docs/ux/tool_atlas.json Generator: docs/ux/mockups/gen_offer_table.py +// Source: scripts/CAD/tool_atlas.json Generator: scripts/CAD/gen_offer_table.py // // The object-driven tool offer (charter 4.1): every verb has ONE row index, that index // is the same in every selection it appears in, and verbs that do not apply are shown diff --git a/src/slic3r/GUI/CAD/DesignPanel.cpp b/src/slic3r/GUI/CAD/DesignPanel.cpp index d247ddfd26..5f64025f2b 100644 --- a/src/slic3r/GUI/CAD/DesignPanel.cpp +++ b/src/slic3r/GUI/CAD/DesignPanel.cpp @@ -1,7 +1,7 @@ #include "slic3r/GUI/CAD/DesignPanel.hpp" #include "slic3r/GUI/CAD/DesignCanvas.hpp" #include "slic3r/GUI/CAD/DesignSketchTool.hpp" -#include "slic3r/GUI/CAD/DesignOffer.hpp" // generated offer table — see docs/ux/tool_atlas.json +#include "slic3r/GUI/CAD/DesignOffer.hpp" // generated offer table — see scripts/CAD/tool_atlas.json #include "libslic3r/CAD/GeometryEngine.hpp" // face_by_index for face-extrude gizmo anchor #include "libslic3r/TriangleMesh.hpp" // mesh import: STL/OBJ -> indexed_triangle_set #include "libslic3r/Format/OBJ.hpp" @@ -6067,7 +6067,7 @@ bool DesignPanel::sketch_plane_target(wxString& what) const // --------------------------------------------------------------------------------------------- // The object-driven offer (charter §4.1). Right-click the geometry and get a vertical list in the // ratified row order, with the verbs that do not apply DISABLED IN PLACE carrying their reason. -// The rows come from DesignOffer.hpp, generated from docs/ux/tool_atlas.json — the same file the +// The rows come from DesignOffer.hpp, generated from scripts/CAD/tool_atlas.json — the same file the // mockups are drawn from, so a drawing and the product cannot drift apart. // --------------------------------------------------------------------------------------------- diff --git a/src/slic3r/GUI/CAD/DesignSketchTool.cpp b/src/slic3r/GUI/CAD/DesignSketchTool.cpp index 716df658ed..c195d6a877 100644 --- a/src/slic3r/GUI/CAD/DesignSketchTool.cpp +++ b/src/slic3r/GUI/CAD/DesignSketchTool.cpp @@ -4034,7 +4034,7 @@ void DesignSketchTool::render_mate_connectors() // the information. The same bear rendered flat vs in relief gives 164 vs 210 lit pixels at 16 // degrees and 66 vs 120 at 6. So the glyph is a small shaded solid, not an outline. // -// The geometry is EMITTED from the real part by doc/design/mate-connectors/emit_glyph_table.py, +// The geometry is EMITTED from the real part by scripts/CAD/mate-glyph/emit_glyph_table.py, // not hand-drawn, so the glyph and the printed connector cannot drift apart. Two vertices stand // above the 3 mm plate in the actual B-rep, which is why the snout here is a tent with one crest // edge and four flanks drafted at 20 degrees rather than anything more elaborate. @@ -4042,7 +4042,7 @@ void DesignSketchTool::render_mate_connectors() // The cheek dot is the handedness mark. Without it the glyph differs from its own mirror by only // 5-9 % of its lit pixels, which is not enough to read; the dot roughly doubles that and, unlike // making the eyes uneven, identifies the side from that cheek alone instead of by comparison. -// Emitted by doc/design/mate-connectors/emit_glyph_table.py from bear.step — do not hand-edit. +// Emitted by scripts/CAD/mate-glyph/emit_glyph_table.py from bear.step — do not hand-edit. // Normalised to the part's bounding span and centred: the renderer scales by one radius. static const Vec2d kBearOutline[] = { // 12 verts, RDP eps 0.030, CCW {+0.3842, +0.3294}, {+0.3156, +0.4002}, {+0.2424, +0.3294},