icadkit 0.3.8__tar.gz → 0.3.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. {icadkit-0.3.8 → icadkit-0.3.9}/Cargo.lock +2 -2
  2. {icadkit-0.3.8 → icadkit-0.3.9}/Cargo.toml +1 -1
  3. {icadkit-0.3.8 → icadkit-0.3.9}/PKG-INFO +29 -42
  4. {icadkit-0.3.8 → icadkit-0.3.9}/README.md +29 -42
  5. {icadkit-0.3.8 → icadkit-0.3.9}/docs/api.md +21 -12
  6. {icadkit-0.3.8 → icadkit-0.3.9}/docs/changelog.md +20 -0
  7. {icadkit-0.3.8 → icadkit-0.3.9}/docs/csg.md +3 -3
  8. {icadkit-0.3.8 → icadkit-0.3.9}/docs/drawing.md +38 -3
  9. {icadkit-0.3.8 → icadkit-0.3.9}/docs/native.md +9 -9
  10. {icadkit-0.3.8 → icadkit-0.3.9}/docs/parts.md +2 -3
  11. {icadkit-0.3.8 → icadkit-0.3.9}/docs/preview.md +3 -3
  12. {icadkit-0.3.8 → icadkit-0.3.9}/docs/saved-bodies.md +16 -16
  13. {icadkit-0.3.8 → icadkit-0.3.9}/docs/support.md +29 -19
  14. {icadkit-0.3.8 → icadkit-0.3.9}/docs/trailer.md +3 -4
  15. {icadkit-0.3.8 → icadkit-0.3.9}/docs/viewer.md +4 -4
  16. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/__init__.py +6 -1
  17. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/cli.py +2 -0
  18. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/models.py +18 -0
  19. icadkit-0.3.9/src/icadkit/versions.py +74 -0
  20. icadkit-0.3.9/src/icadkit/views.py +310 -0
  21. icadkit-0.3.9/tests/test_views_placement.py +155 -0
  22. icadkit-0.3.8/src/icadkit/views.py +0 -138
  23. {icadkit-0.3.8 → icadkit-0.3.9}/COMMERCIAL-LICENSE.md +0 -0
  24. {icadkit-0.3.8 → icadkit-0.3.9}/LICENSE +0 -0
  25. {icadkit-0.3.8 → icadkit-0.3.9}/LICENSES/Apache-2.0.txt +0 -0
  26. {icadkit-0.3.8 → icadkit-0.3.9}/LICENSES/PolyForm-Noncommercial-1.0.0.md +0 -0
  27. {icadkit-0.3.8 → icadkit-0.3.9}/LICENSES/parasolid-core-MIT.txt +0 -0
  28. {icadkit-0.3.8 → icadkit-0.3.9}/LICENSES/rust-dependencies.txt +0 -0
  29. {icadkit-0.3.8 → icadkit-0.3.9}/THIRD_PARTY_NOTICES.md +0 -0
  30. {icadkit-0.3.8 → icadkit-0.3.9}/corpus/README.md +0 -0
  31. {icadkit-0.3.8 → icadkit-0.3.9}/corpus/generate.py +0 -0
  32. {icadkit-0.3.8 → icadkit-0.3.9}/corpus/public.jsonl +0 -0
  33. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/Cargo.toml +0 -0
  34. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/LICENSE +0 -0
  35. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/build.rs +0 -0
  36. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/compression.rs +0 -0
  37. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/container.rs +0 -0
  38. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/document.rs +0 -0
  39. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/error.rs +0 -0
  40. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/header.rs +0 -0
  41. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/lib.rs +0 -0
  42. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/limits.rs +0 -0
  43. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/native.rs +0 -0
  44. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/parasolid.rs +0 -0
  45. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/parts.rs +0 -0
  46. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/provenance.rs +0 -0
  47. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/reader.rs +0 -0
  48. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/record.rs +0 -0
  49. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/resource.rs +0 -0
  50. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/schema.rs +0 -0
  51. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/trailer.rs +0 -0
  52. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/src/views.rs +0 -0
  53. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/tests/container.rs +0 -0
  54. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/tests/header.rs +0 -0
  55. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-core/tests/resources.rs +0 -0
  56. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/Cargo.toml +0 -0
  57. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/LICENSE +0 -0
  58. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/src/brep.rs +0 -0
  59. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/src/document.rs +0 -0
  60. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/src/geometry.rs +0 -0
  61. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/src/lib.rs +0 -0
  62. {icadkit-0.3.8 → icadkit-0.3.9}/crates/icad-python/src/schema.rs +0 -0
  63. {icadkit-0.3.8 → icadkit-0.3.9}/docs/license.md +0 -0
  64. {icadkit-0.3.8 → icadkit-0.3.9}/docs/parameters.md +0 -0
  65. {icadkit-0.3.8 → icadkit-0.3.9}/docs/references.md +0 -0
  66. {icadkit-0.3.8 → icadkit-0.3.9}/docs/roadmap.md +0 -0
  67. {icadkit-0.3.8 → icadkit-0.3.9}/docs/shapes.md +0 -0
  68. {icadkit-0.3.8 → icadkit-0.3.9}/docs/writing.md +0 -0
  69. {icadkit-0.3.8 → icadkit-0.3.9}/pyproject.toml +0 -0
  70. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/bump_version.py +0 -0
  71. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/check_license.py +0 -0
  72. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/check_public_tree.py +0 -0
  73. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/test_publication.py +0 -0
  74. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/test_versions.py +0 -0
  75. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/verify_artifacts.py +0 -0
  76. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/verify_corpus.py +0 -0
  77. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/verify_install.py +0 -0
  78. {icadkit-0.3.8 → icadkit-0.3.9}/scripts/verify_native_corpus.py +0 -0
  79. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/__main__.py +0 -0
  80. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_core.pyi +0 -0
  81. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_csg_occt.py +0 -0
  82. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_preview_bridge.py +0 -0
  83. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_saved_occt.py +0 -0
  84. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_shape_occt.py +0 -0
  85. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_viewer/index.html +0 -0
  86. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_viewer/viewer.css +0 -0
  87. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_viewer/viewer.js +0 -0
  88. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/_viewer_io.py +0 -0
  89. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/api.py +0 -0
  90. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/container.py +0 -0
  91. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/csg.py +0 -0
  92. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/document.py +0 -0
  93. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/drawing.py +0 -0
  94. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/errors.py +0 -0
  95. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/geometry.py +0 -0
  96. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/native.py +0 -0
  97. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/parameters.py +0 -0
  98. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/parts.py +0 -0
  99. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/preview.py +0 -0
  100. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/py.typed +0 -0
  101. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/references.py +0 -0
  102. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/saved.py +0 -0
  103. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/schema.py +0 -0
  104. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/shape.py +0 -0
  105. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/trailer.py +0 -0
  106. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/viewer.py +0 -0
  107. {icadkit-0.3.8 → icadkit-0.3.9}/src/icadkit/write.py +0 -0
  108. {icadkit-0.3.8 → icadkit-0.3.9}/tests/conftest.py +0 -0
  109. {icadkit-0.3.8 → icadkit-0.3.9}/tests/drawing_fixtures.py +0 -0
  110. {icadkit-0.3.8 → icadkit-0.3.9}/tests/fixture_builders.py +0 -0
  111. {icadkit-0.3.8 → icadkit-0.3.9}/tests/geometry_fixtures.py +0 -0
  112. {icadkit-0.3.8 → icadkit-0.3.9}/tests/parameter_fixtures.py +0 -0
  113. {icadkit-0.3.8 → icadkit-0.3.9}/tests/part_fixtures.py +0 -0
  114. {icadkit-0.3.8 → icadkit-0.3.9}/tests/preview_fixtures.py +0 -0
  115. {icadkit-0.3.8 → icadkit-0.3.9}/tests/saved_fixtures.py +0 -0
  116. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_api.py +0 -0
  117. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_cli.py +0 -0
  118. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_container.py +0 -0
  119. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_corpus.py +0 -0
  120. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_csg.py +0 -0
  121. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_distribution.py +0 -0
  122. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_drawing.py +0 -0
  123. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_extrusion.py +0 -0
  124. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_followup_parts.py +0 -0
  125. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_geometry.py +0 -0
  126. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_inspect.py +0 -0
  127. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_legacy_parts.py +0 -0
  128. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_mirrors.py +0 -0
  129. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_native.py +0 -0
  130. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_native_corpus.py +0 -0
  131. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_native_round.py +0 -0
  132. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_parameters.py +0 -0
  133. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_part_profiles.py +0 -0
  134. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_part_semantics.py +0 -0
  135. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_parts.py +0 -0
  136. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_parts_material.py +0 -0
  137. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_preview.py +0 -0
  138. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_profile_shapes.py +0 -0
  139. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_references.py +0 -0
  140. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_resource_cli.py +0 -0
  141. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_resources.py +0 -0
  142. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_saved.py +0 -0
  143. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_shape.py +0 -0
  144. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_trailer.py +0 -0
  145. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_v7_parts.py +0 -0
  146. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_v8l4_boundary.py +0 -0
  147. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_version_geometry.py +0 -0
  148. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_viewer.py +0 -0
  149. {icadkit-0.3.8 → icadkit-0.3.9}/tests/test_write.py +0 -0
  150. {icadkit-0.3.8 → icadkit-0.3.9}/tests/trailer_fixtures.py +0 -0
  151. {icadkit-0.3.8 → icadkit-0.3.9}/tests/viewer_assembly_browser.mjs +0 -0
  152. {icadkit-0.3.8 → icadkit-0.3.9}/tests/viewer_browser.mjs +0 -0
  153. {icadkit-0.3.8 → icadkit-0.3.9}/tests/viewer_mirror_browser.mjs +0 -0
  154. {icadkit-0.3.8 → icadkit-0.3.9}/uv.lock +0 -0
@@ -89,7 +89,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
89
89
 
90
90
  [[package]]
91
91
  name = "icad-core"
92
- version = "0.3.8"
92
+ version = "0.3.9"
93
93
  dependencies = [
94
94
  "flate2",
95
95
  "parasolid-core",
@@ -99,7 +99,7 @@ dependencies = [
99
99
 
100
100
  [[package]]
101
101
  name = "icad-python"
102
- version = "0.3.8"
102
+ version = "0.3.9"
103
103
  dependencies = [
104
104
  "icad-core",
105
105
  "parasolid-core",
@@ -4,7 +4,7 @@ resolver = "3"
4
4
 
5
5
  [workspace.package]
6
6
  # Release version source. Update with: python3 scripts/bump_version.py X.Y.Z
7
- version = "0.3.8"
7
+ version = "0.3.9"
8
8
  edition = "2024"
9
9
  rust-version = "1.88"
10
10
  license = "PolyForm-Noncommercial-1.0.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: icadkit
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Classifier: Development Status :: 2 - Pre-Alpha
5
5
  Classifier: Programming Language :: Python :: 3 :: Only
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -32,31 +32,17 @@ A Rust-based Python reader for **iCAD SX `.icd` files**. Read saved part
32
32
  structure, coordinate frames, names and selected attributes; inspect native
33
33
  box/cylinder parameters; and extract embedded Parasolid geometry.
34
34
 
35
- Version **0.3.7** added:
35
+ Supported workflows include:
36
36
 
37
- - [Saved final bodies](docs/saved-bodies.md) on rolling-ball blend surfaces
38
- and on toroidal faces that reach their axis, through `parasolid-core 0.3.7`
39
- and the `preview` extra pinned to `parasolid-kit[occt]==0.3.7`. The local
40
- sample rises from 28,896 to 29,386 of 29,703 bound bodies, with the
41
- previously converted bodies unchanged.
42
- - One declaration per backend version (`Cargo.toml`, `pyproject.toml`); the
43
- runtime checks of the backend version are gone.
44
-
45
- Version 0.3.6 added [saved final bodies](docs/saved-bodies.md) on spun
46
- surfaces (SPUN_SURF), line/arc profile extrusions as [CSG](docs/csg.md)
47
- operands and decoded surface and edge items of the
48
- [trailing container](docs/trailer.md).
49
-
50
- Version 0.3.5 added [view inventories and saved 2D geometry](docs/drawing.md),
51
- twenty-six further catalog-free [schema keys](docs/support.md#schemas), the
52
- [trailing container](docs/trailer.md), saved final bodies bound through V8
53
- association records and V7 source IDs, more [native primitives](docs/native.md),
54
- [saved 3D parameter tables](docs/parameters.md) and explicit
55
- [external-reference resolution](docs/references.md).
56
-
57
- Version 0.3.0 added the [native file viewer](docs/viewer.md), broader
58
- [part access](docs/parts.md), optional [V7L7 boolean evaluation](docs/csg.md)
59
- and [saved final body display](docs/saved-bodies.md).
37
+ - [Part access](docs/parts.md), [saved 3D parameter tables](docs/parameters.md)
38
+ and explicit [external-reference resolution](docs/references.md).
39
+ - [View inventories and saved 2D geometry](docs/drawing.md), plus decoded
40
+ surface and edge items of the [trailing container](docs/trailer.md).
41
+ - The [native file viewer](docs/viewer.md) for qualified
42
+ [native primitives](docs/native.md) and their part properties.
43
+ - Optional [V7L7 boolean evaluation](docs/csg.md) and
44
+ [saved final body display](docs/saved-bodies.md), including qualified spun,
45
+ rolling-ball blend and toroidal surfaces.
60
46
 
61
47
  icadkit is experimental. Unsupported geometry remains in the part inventory;
62
48
  unknown values and source ranges are preserved. Part frames, native primitive
@@ -96,21 +82,24 @@ from it, and `icadkit.__version__` / the CLI use the installed package metadata.
96
82
  With Python 3.11+, Cargo and uv available, update it with one command:
97
83
 
98
84
  ```sh
99
- python3 scripts/bump_version.py 0.3.8
100
- python3 scripts/bump_version.py --check --tag v0.3.8
85
+ python3 scripts/bump_version.py X.Y.Z
86
+ python3 scripts/bump_version.py --check --tag vX.Y.Z
101
87
  ```
102
88
 
103
- The version above is an example. The command updates the workspace version,
104
- synchronizes `Cargo.lock` and `uv.lock`, and checks their consistency. On failure
105
- it restores all three files. Add `--offline` to use cached dependencies. Stable
89
+ Replace `X.Y.Z` with the intended release number. The command updates the
90
+ workspace version, synchronizes `Cargo.lock` and `uv.lock`, and checks their
91
+ consistency. On failure it restores all three files. Add `--offline` to use
92
+ cached dependencies. Stable
106
93
  `X.Y.Z` and development `X.Y.Z-dev.N` versions are supported; Python metadata
107
94
  uses `X.Y.Z.devN` for the latter. `--check` does not modify the source or locks.
108
95
  CI checks the same rules and requires release tags to match the source version.
109
96
 
110
- The `parasolid-core` and `parasolid-kit` dependency pins have their own versions
111
- and are updated separately. Historical versions in this README and the
112
- [changelog](docs/changelog.md) describe when features were introduced; retain
113
- those numbers and write new release notes when preparing a release.
97
+ Use `icadkit --version` to check the installed package version and `icadkit info`
98
+ to inspect its backend version. The `parasolid-core` and `parasolid-kit`
99
+ dependency pins have their own versions and are updated separately.
100
+ Usage guides describe capabilities without repeating the package version.
101
+ Record version-specific changes in the [changelog](docs/changelog.md); retain
102
+ the release numbers attached to historical notes and validation results.
114
103
 
115
104
  ## Part structure, frames and attributes
116
105
 
@@ -144,14 +133,12 @@ spherical, conical and toroidal surfaces. V8L3 resource sharing preserves each
144
133
  occurrence's saved placement. An explicit schema catalog is needed when the
145
134
  exact built-in profile lacks a required type. Counted metadata framing also
146
135
  extends part inventories while preserving unknown records and diagnostics.
147
- Version 0.3.0 also preserves bounded binary attributes as raw owned records,
148
- reads V8L1/V8L2 part inventories without assigning units or geometry, and displays
149
- native cones/frusta and full ring tori. The updated exact V34 profile in
150
- `parasolid-core 0.3.1` removes the catalog requirement for qualified toroidal
151
- resources.
152
-
153
- Version 0.3.5 extends qualified millimetre frames and bounded
154
- native/saved geometry to V7L6/V7L7 and V8L1/V8L2/V8L3, including internal mirrors.
136
+ Bounded binary attributes are preserved as raw owned records. The native viewer
137
+ also displays qualified cones/frusta and full ring tori. The built-in exact V34
138
+ profile covers qualified toroidal resources without an external catalog.
139
+
140
+ Qualified millimetre frames and bounded native/saved geometry cover
141
+ V7L6/V7L7 and V8L1/V8L2/V8L3, including internal mirrors.
155
142
  Signed occurrence orientation is separate from already placed geometry; see
156
143
  [mirror semantics](docs/parts.md#coordinate-frames-and-units). Explicit
157
144
  [external-reference resolution](docs/references.md) now composes qualified child
@@ -4,31 +4,17 @@ A Rust-based Python reader for **iCAD SX `.icd` files**. Read saved part
4
4
  structure, coordinate frames, names and selected attributes; inspect native
5
5
  box/cylinder parameters; and extract embedded Parasolid geometry.
6
6
 
7
- Version **0.3.7** added:
8
-
9
- - [Saved final bodies](docs/saved-bodies.md) on rolling-ball blend surfaces
10
- and on toroidal faces that reach their axis, through `parasolid-core 0.3.7`
11
- and the `preview` extra pinned to `parasolid-kit[occt]==0.3.7`. The local
12
- sample rises from 28,896 to 29,386 of 29,703 bound bodies, with the
13
- previously converted bodies unchanged.
14
- - One declaration per backend version (`Cargo.toml`, `pyproject.toml`); the
15
- runtime checks of the backend version are gone.
16
-
17
- Version 0.3.6 added [saved final bodies](docs/saved-bodies.md) on spun
18
- surfaces (SPUN_SURF), line/arc profile extrusions as [CSG](docs/csg.md)
19
- operands and decoded surface and edge items of the
20
- [trailing container](docs/trailer.md).
21
-
22
- Version 0.3.5 added [view inventories and saved 2D geometry](docs/drawing.md),
23
- twenty-six further catalog-free [schema keys](docs/support.md#schemas), the
24
- [trailing container](docs/trailer.md), saved final bodies bound through V8
25
- association records and V7 source IDs, more [native primitives](docs/native.md),
26
- [saved 3D parameter tables](docs/parameters.md) and explicit
27
- [external-reference resolution](docs/references.md).
28
-
29
- Version 0.3.0 added the [native file viewer](docs/viewer.md), broader
30
- [part access](docs/parts.md), optional [V7L7 boolean evaluation](docs/csg.md)
31
- and [saved final body display](docs/saved-bodies.md).
7
+ Supported workflows include:
8
+
9
+ - [Part access](docs/parts.md), [saved 3D parameter tables](docs/parameters.md)
10
+ and explicit [external-reference resolution](docs/references.md).
11
+ - [View inventories and saved 2D geometry](docs/drawing.md), plus decoded
12
+ surface and edge items of the [trailing container](docs/trailer.md).
13
+ - The [native file viewer](docs/viewer.md) for qualified
14
+ [native primitives](docs/native.md) and their part properties.
15
+ - Optional [V7L7 boolean evaluation](docs/csg.md) and
16
+ [saved final body display](docs/saved-bodies.md), including qualified spun,
17
+ rolling-ball blend and toroidal surfaces.
32
18
 
33
19
  icadkit is experimental. Unsupported geometry remains in the part inventory;
34
20
  unknown values and source ranges are preserved. Part frames, native primitive
@@ -68,21 +54,24 @@ from it, and `icadkit.__version__` / the CLI use the installed package metadata.
68
54
  With Python 3.11+, Cargo and uv available, update it with one command:
69
55
 
70
56
  ```sh
71
- python3 scripts/bump_version.py 0.3.8
72
- python3 scripts/bump_version.py --check --tag v0.3.8
57
+ python3 scripts/bump_version.py X.Y.Z
58
+ python3 scripts/bump_version.py --check --tag vX.Y.Z
73
59
  ```
74
60
 
75
- The version above is an example. The command updates the workspace version,
76
- synchronizes `Cargo.lock` and `uv.lock`, and checks their consistency. On failure
77
- it restores all three files. Add `--offline` to use cached dependencies. Stable
61
+ Replace `X.Y.Z` with the intended release number. The command updates the
62
+ workspace version, synchronizes `Cargo.lock` and `uv.lock`, and checks their
63
+ consistency. On failure it restores all three files. Add `--offline` to use
64
+ cached dependencies. Stable
78
65
  `X.Y.Z` and development `X.Y.Z-dev.N` versions are supported; Python metadata
79
66
  uses `X.Y.Z.devN` for the latter. `--check` does not modify the source or locks.
80
67
  CI checks the same rules and requires release tags to match the source version.
81
68
 
82
- The `parasolid-core` and `parasolid-kit` dependency pins have their own versions
83
- and are updated separately. Historical versions in this README and the
84
- [changelog](docs/changelog.md) describe when features were introduced; retain
85
- those numbers and write new release notes when preparing a release.
69
+ Use `icadkit --version` to check the installed package version and `icadkit info`
70
+ to inspect its backend version. The `parasolid-core` and `parasolid-kit`
71
+ dependency pins have their own versions and are updated separately.
72
+ Usage guides describe capabilities without repeating the package version.
73
+ Record version-specific changes in the [changelog](docs/changelog.md); retain
74
+ the release numbers attached to historical notes and validation results.
86
75
 
87
76
  ## Part structure, frames and attributes
88
77
 
@@ -116,14 +105,12 @@ spherical, conical and toroidal surfaces. V8L3 resource sharing preserves each
116
105
  occurrence's saved placement. An explicit schema catalog is needed when the
117
106
  exact built-in profile lacks a required type. Counted metadata framing also
118
107
  extends part inventories while preserving unknown records and diagnostics.
119
- Version 0.3.0 also preserves bounded binary attributes as raw owned records,
120
- reads V8L1/V8L2 part inventories without assigning units or geometry, and displays
121
- native cones/frusta and full ring tori. The updated exact V34 profile in
122
- `parasolid-core 0.3.1` removes the catalog requirement for qualified toroidal
123
- resources.
124
-
125
- Version 0.3.5 extends qualified millimetre frames and bounded
126
- native/saved geometry to V7L6/V7L7 and V8L1/V8L2/V8L3, including internal mirrors.
108
+ Bounded binary attributes are preserved as raw owned records. The native viewer
109
+ also displays qualified cones/frusta and full ring tori. The built-in exact V34
110
+ profile covers qualified toroidal resources without an external catalog.
111
+
112
+ Qualified millimetre frames and bounded native/saved geometry cover
113
+ V7L6/V7L7 and V8L1/V8L2/V8L3, including internal mirrors.
127
114
  Signed occurrence orientation is separate from already placed geometry; see
128
115
  [mirror semantics](docs/parts.md#coordinate-frames-and-units). Explicit
129
116
  [external-reference resolution](docs/references.md) now composes qualified child
@@ -8,8 +8,8 @@ and model boundaries, see [supported capabilities](support.md).
8
8
 
9
9
  The public Python interface consists of the names in `icadkit.__all__` and
10
10
  the documented names in the optional [icadkit.preview module](preview.md).
11
- Version 0.3.0 also exposes [icadkit.viewer](viewer.md) for native
12
- qualified analytic primitive display and part/property inspection without optional dependencies.
11
+ The [icadkit.viewer module](viewer.md) displays qualified native analytic
12
+ primitives and provides part/property inspection without optional dependencies.
13
13
  `icadkit._core`, native handles and attributes beginning with `_` are private.
14
14
  Within a minor release series, existing arguments, result fields, diagnostic codes, coordinate
15
15
  semantics and CLI exit codes are preserved. Message wording and human-readable
@@ -20,25 +20,26 @@ Removing existing fields or changing their meanings requires a schema version
20
20
  change. A `complete` status always refers to an explicit scope, not the whole
21
21
  ICD model.
22
22
 
23
- Version 0.2.0 adds [native part access](parts.md) through
24
- `Document.read_parts()`, returning `PartIndex`, `Part`, `PartDefinition`,
25
- `PartReference`, `PartPlacement` and `PartProperty`. Version 0.3.0 adds
26
- `PartOpaqueAttribute` for retained binary attribute records. It exposes qualified part
27
- frames and selected stored attributes. Its scope statuses are independent of
23
+ [Native part access](parts.md) uses `Document.read_parts()`, returning
24
+ `PartIndex`, `Part`, `PartDefinition`, `PartReference`, `PartPlacement` and
25
+ `PartProperty`, with `PartOpaqueAttribute` for retained binary attribute records.
26
+ The part API exposes qualified part frames and selected stored attributes.
27
+ Its scope statuses are independent of
28
28
  the resource geometry API described below. Saved entities expose
29
29
  `NativeEntity`, `NativeAppearance` and `NativePrimitive`; see
30
30
  [native parameter and appearance access](native.md).
31
- Version 0.3.5 adds [saved 3D parameter tables](parameters.md) through
31
+ [Saved 3D parameter tables](parameters.md) are available through
32
32
  `Document.read_parameters()`, returning `ParameterIndex`, `SavedParameter`,
33
33
  `ParameterCondition` and `ParameterTable`, with `ParameterLimits` for bounded
34
34
  allocation. These saved formulas and values are independent of primitive geometry.
35
- It adds [views and saved 2D entities](drawing.md):
36
- `Document.read_views()` returns `ViewIndex`, `View` and `ViewEntry`, bounded by
35
+ For [views and saved 2D entities](drawing.md),
36
+ `Document.read_views()` returns `ViewIndex`, `View`, `ViewEntry` and `ViewPlacement`
37
+ (the [sheet placement](drawing.md#view-placement-on-the-sheet) of each 2D view), bounded by
37
38
  `ViewLimits`; `Document.read_drawing()` returns `DrawingIndex`, `DrawingEntity`,
38
39
  `DrawingPrimitive` and `DrawingText`, with `DrawingLimits`. The `views` and
39
40
  `drawing` CLI commands expose classification, scoped status and source ranges.
40
41
  These APIs do not combine 2D geometry with the native 3D part API.
41
- It also adds [explicit assembly resolution](references.md):
42
+ [Explicit assembly resolution](references.md) uses
42
43
  `read_assembly()` / `Document.read_assembly()`, `AssemblyLimits`, `ReferenceRequest`,
43
44
  `ReferenceResolver`, `AssemblyReference`, `AssemblyDocument`, `AssemblyOccurrence`,
44
45
  `AssemblyEntity` and `AssemblyIndex`. `read_parts()` retains its single-file
@@ -103,7 +104,15 @@ returns its byte length. `RecordInfo.payload_range` excludes the eight-byte
103
104
  opening tag/length and four-byte closing tag. A valid range does not imply that
104
105
  its contents or references have been interpreted.
105
106
 
106
- `Header.raw_version` is not converted to an iCAD product version.
107
+ `Header.raw_version` is not converted to an iCAD product version by the native
108
+ reader. `Header.version_label` (`V8L3`) and `Header.version` (`(8, 3)`) read the
109
+ observed `00 major 00 level` layout of those bytes in either byte order, and
110
+ `None` for any other layout; `icadkit.version_label(raw)` is the same function.
111
+ A label is the version as saved, not a support claim: `icadkit.qualified_versions()`
112
+ returns a `VersionSupport` with the labels each scope has been qualified for
113
+ (`parts`, `views_little`, `views_big`, `drawing_layout`, and `views(byte_order)`),
114
+ so a caller can say that a `V8L4` file is unqualified before any scope reports
115
+ its `*.profile` diagnostic. `icadkit inspect --json` includes `version_label`.
107
116
  `raw_name` preserves padding. `name_cp932_candidate` removes trailing spaces
108
117
  and NULs, then strictly decodes CP932. Interior NULs remain. A decoding failure
109
118
  returns `None` and `header.name_decode_failed`, retaining the original bytes.
@@ -4,6 +4,23 @@
4
4
 
5
5
  ### Added
6
6
 
7
+ - `View.placement` and `ViewIndex.placements` decode the 264-byte control
8
+ records of the 2D global view as `ViewPlacement`: the view origin on the
9
+ sheet (millimetres of the 2D global view), the view scale, the saved record
10
+ identifier and the 2D view name, in the file byte order. Records are matched
11
+ to `2d_view` entries by name; `views.placement`, `views.placement_view`,
12
+ `views.placement_ambiguous` and `views.placement_missing` report deviating
13
+ records, records without a view, repeated names and views without a record.
14
+ Geometry stays view-local; see [view placement](drawing.md#view-placement-on-the-sheet).
15
+ In the installed corpus 817 of 855 2D views have a record and every one
16
+ agrees with the view header's scale.
17
+ - `Header.version_label` (`V8L3`), `Header.version` (`(8, 3)`),
18
+ `icadkit.version_label()` and `icadkit.qualified_versions()`
19
+ (`VersionSupport`) name the saved product version and the versions each
20
+ scope is qualified for, so an unqualified version such as `V8L4` can be
21
+ reported before its `*.profile` diagnostics. `icadkit inspect --json` adds
22
+ `version_label`.
23
+
7
24
  - `Document.to_bytes()` serializes the directory-indexed container with its
8
25
  framing recomputed (directory offsets and lengths, `RES`/`V/W` length
9
26
  words, the MOD total-word field) while unknown fields, record payloads, the
@@ -90,6 +107,9 @@
90
107
  CI checks crate inheritance, dynamic Python metadata, lock versions and
91
108
  release tags. Dependency versions and historical release notes remain
92
109
  independent of the package version.
110
+ - README and usage guides describe capabilities without repeating the package
111
+ release number. Version-update examples use placeholders; historical release
112
+ notes and validation results retain the versions they describe.
93
113
  - The authored framing fixtures (`tests/fixture_builders.py`, the public
94
114
  corpus) now store the MOD total-word count the way every observed iCAD
95
115
  file does, so `corpus/public.jsonl` pins new hashes for the same eight
@@ -1,6 +1,6 @@
1
1
  # Bounded V7L7 CSG
2
2
 
3
- Version 0.3.0 reads selected saved V7L7 final-body programs.
3
+ The CSG API reads selected saved V7L7 final-body programs.
4
4
  `read_csg()` is dependency-free. `evaluate_csg()` uses the optional `preview`
5
5
  extra to evaluate analytic solids with OCCT and generate a display mesh.
6
6
  This is partial model support; it does not reconstruct feature history or
@@ -41,12 +41,12 @@ not interpret those feature operations.
41
41
  - Saved postfix union, difference and intersection of positive-height boxes and
42
42
  cylinders, including the qualified saved checkpoints between operations.
43
43
  Multiple independent owners and disconnected solid results are supported.
44
- - Version 0.3.5 also accepts six-vertex prism operands: a frame, a signed
44
+ - Six-vertex prism operands: a frame, a signed
45
45
  height along its Z axis and six XY vertices of a strictly convex profile. A
46
46
  negative height moves the base along the axis; the frame stays rigid and the
47
47
  profile is used as saved. The operand is exposed as a `polygon_extrusion`
48
48
  primitive with `profile_points`. Other profiles are `csg.operand_layout`.
49
- - Version 0.3.6 also accepts profile extrusion operands: the
49
+ - Profile extrusion operands: the
50
50
  variable-length line/arc layout of [native primitives](native.md), with a
51
51
  frame, a signed height and a closed profile decoded by the same core rules as
52
52
  a standalone record. A negative height moves the base along the axis, as for
@@ -1,7 +1,7 @@
1
1
  # Views and saved 2D entities
2
2
 
3
- Version 0.3.5 adds `Document.read_views()` and `Document.read_drawing()`.
4
- Both read originals directly, including registered part files. No iCAD process,
3
+ `Document.read_views()` and `Document.read_drawing()` read originals directly,
4
+ including registered part files. No iCAD process,
5
5
  resave, optional geometry package or schema catalog is needed.
6
6
 
7
7
  ```python
@@ -80,6 +80,41 @@ Their numeric links and optional name bytes remain opaque `metadata` with no
80
80
  owner or geometry assigned. Local checks traverse the ten previously stopped
81
81
  files; this does not qualify legacy assembly or external-reference semantics.
82
82
 
83
+ ## View placement on the sheet
84
+
85
+ The 2D global view stores one fixed-length control record per 2D view after
86
+ its entity group: a `0x40000000` marker followed by 264-byte records. The
87
+ reader decodes them as `ViewPlacement` (the `placements` of the `ViewIndex`)
88
+ and attaches each record to the `2d_view` whose name it carries
89
+ (`View.placement`). Nothing is applied to the entities: `read_drawing()` keeps
90
+ view-local millimetres, and a caller composes the sheet by scaling a view's
91
+ geometry by `placement.scale` and translating it to `placement.origin`.
92
+
93
+ | Field | Record offset | Meaning |
94
+ | --- | --- | --- |
95
+ | `source_id` | `+16` (u32) | The saved record identifier |
96
+ | `origin` | `+40`, `+48` (two doubles) | The view origin on the sheet, in millimetres of the 2D global view; the third double at `+56` is retained raw |
97
+ | `scale` | `+64` (double) | The view scale; it equals the view header's `scale` in every observed file |
98
+ | `raw_name` / `name` | `+136` (8 bytes, CP932) | The 2D view the record belongs to |
99
+
100
+ Numeric values follow the file byte order. The length word at `+0`, a finite
101
+ origin and a positive scale make a record `complete`; a deviating value keeps
102
+ the record with `views.placement` diagnostics and `status="invalid"`, and an
103
+ invalid scale is reported as `None`. The other words (`+12`, `+24`–`+40`,
104
+ `+72`–`+136` and `+144`–`+264`, including the six floats at `+176` that are not
105
+ a view extent in saved files) retain their bytes without an assigned meaning.
106
+ Records that name no 2D view add `views.placement_view`, several records with
107
+ one name add `views.placement_ambiguous` and map to no view, and a 2D view
108
+ without a record adds `views.placement_missing`; these diagnostics do not
109
+ change the index status, which describes framing only. `DrawingWriter` writes
110
+ the same record for each view it adds.
111
+
112
+ In the installed corpus (1,449 distinct files), 701 documents have a 2D global
113
+ view (316 big-endian, 385 little-endian), all of them with a placement list:
114
+ 818 records are complete, 817 of the 855 2D views have a record and every one
115
+ of those agrees with the view header's scale; 38 views have no record and one
116
+ record names no 2D view.
117
+
83
118
  ## Drawing scope
84
119
 
85
120
  `DrawingIndex` contains the view inventory and bounded 2D `DrawingEntity` records.
@@ -161,7 +196,7 @@ spacing. Point lists that do not close, unobserved item words or nonpositive
161
196
  lengths keep the entity `partial` with `drawing.hatch_boundary` or
162
197
  `drawing.hatch_fields`.
163
198
 
164
- Geometry uses **view-local millimetres**. It does not apply paper placement,
199
+ Geometry uses **view-local millimetres**. It does not apply the [view placement](#view-placement-on-the-sheet),
165
200
  view rotation, scale or a 3D projection transform. Saved line/circle records in
166
201
  a projected view can be read independently of the unimplemented projection
167
202
  relationship. Fonts, glyph outlines, tilt and legacy CP932 text runs remain unqualified;
@@ -4,13 +4,13 @@ For qualified V7L7 final boolean bodies, use the separate [CSG API](csg.md)
4
4
  or `view --csg` with the `preview` extra. The native-primitive scope described
5
5
  here keeps operands opaque.
6
6
 
7
- Version **0.2.0** adds saved native entities to `Document.read_parts()`.
7
+ `Document.read_parts()` exposes saved native entities.
8
8
  It reads qualified V8L3 boxes and cylinders, and selected stored appearance
9
9
  fields. It does not evaluate native B-Rep, CSG, tessellation or a complete scene.
10
10
 
11
- The 0.3.0 [native viewer](viewer.md) can tessellate the supported
11
+ The [native viewer](viewer.md) can tessellate the supported
12
12
  box/cylinder/full-sphere/cone/torus parameters for an explicitly partial display with a part tree.
13
- Version 0.3.5 also decodes qualified V7L6/V7L7/V8L1/V8L2 standalone primitive
13
+ The reader also decodes qualified V7L6/V7L7/V8L1/V8L2 standalone primitive
14
14
  owners and saved entity appearance. These profiles require a complete saved hierarchy/index and
15
15
  an entire internal owner's list of qualified primitive
16
16
  headers. An unknown or CSG record keeps the whole owner's list opaque; primitive
@@ -55,8 +55,8 @@ from that entity to `Document.resources` is inferred.
55
55
 
56
56
  ## Primitive contract
57
57
 
58
- In version 0.3.0, `NativePrimitive.kind` is `box`, `cylinder`, `sphere`,
59
- `cone` or `torus`.
58
+ `NativePrimitive.kind` is `box`, `cylinder`, `sphere`, `cone`, `torus`,
59
+ `polygon_extrusion`, `profile_extrusion` or `revolution`.
60
60
  The qualified layout retains:
61
61
 
62
62
  | Field | Box | Cylinder |
@@ -82,8 +82,8 @@ axis of revolution. `radius` and `height` are `None`. Partial sweeps, horn/spind
82
82
  tori and unknown extents remain unsupported. These added fields are `None` for
83
83
  other primitive kinds. Boxes remain the only kind with non-null box bounds.
84
84
 
85
- The `polygon_extrusion` kind, added in 0.3.5, exposes six distinct XY vertices in
86
- `profile_points` and a positive `height`. Its qualified 368-byte record stores
85
+ The `polygon_extrusion` kind exposes six distinct XY vertices in `profile_points`
86
+ and a positive `height`. Its qualified 368-byte record stores
87
87
  two identical closed straight profiles and a zero trailer. Concave and convex
88
88
  simple polygons are accepted in either winding. The viewer triangulates both
89
89
  caps and preserves outward winding. Mirrored records with the qualified negative
@@ -232,7 +232,7 @@ Incorrect unit scaling, repeated part transforms and transposed rotation are
232
232
  negative controls. CAD files, SDK binaries and vendor catalogs are not distributed;
233
233
  public tests use independently authored synthetic records and malformed inputs.
234
234
 
235
- For the 0.3.5 cylinder sign, profile extrusion and revolution layouts,
235
+ For the cylinder sign, profile extrusion and revolution layouts,
236
236
  saved SDK observations match volume, area and centroid for 290 negative-height
237
237
  cylinders (30 of them mirrored), 83 profile extrusions (19 mirrored) and 133
238
238
  revolutions (58 mirrored). In a local sample all 6,638 extrusion records of this
@@ -244,7 +244,7 @@ inputs; the [CSG reader](csg.md) decodes them as operands. A profile extrusion
244
244
  that is the only record of a saved single-leaf body is likewise read by the CSG
245
245
  reader, with the same profile rules, and not by this inventory.
246
246
 
247
- The v0.3 additions have offline checks against saved/reopened SDK
247
+ Cone/frustum/torus support has offline checks against saved/reopened SDK
248
248
  observations for ten cone/frustum/torus files, including oblique and dimension
249
249
  holdouts in V7L7/V8L3. Analytic volume, surface area, centroid and stored appearance
250
250
  match; this is not a fresh SDK run or native older-product qualification.
@@ -1,6 +1,6 @@
1
1
  # Native parts
2
2
 
3
- The big-endian V6L1/V6L2/V7L1 `61000001` profiles added in 0.3.5 provide internal
3
+ The big-endian V6L1/V6L2/V7L1 `61000001` profiles provide internal
4
4
  part inventories, names/comments and bounded hierarchy links. Both coordinate
5
5
  blocks are retained as raw values; `entity_policy=inventory_only`,
6
6
  `coordinate_convention=unqualified` and `source_length_unit=None` prevent
@@ -24,7 +24,6 @@ For qualified V7L7 final boolean bodies, use the separate [CSG API](csg.md)
24
24
  or `view --csg` with the `preview` extra. The native-primitive scope described
25
25
  here keeps operands opaque.
26
26
 
27
- Added in **0.2.0**.
28
27
  Read saved part structure, coordinate frames, names, comments and selected
29
28
  extended information without installing iCAD or a geometry schema catalog.
30
29
 
@@ -67,7 +66,7 @@ remains `unknown`: no saved discriminator between a normal document and a
67
66
  registered library part has been qualified. Names and filename suffixes are not
68
67
  used to infer this distinction.
69
68
 
70
- Version 0.3.5 reads observed little-endian V7L2–V7L7 and V8L1–V8L3
69
+ The reader supports observed little-endian V7L2–V7L7 and V8L1–V8L3
71
70
  `3DGLOBAL` layouts. Each version has an explicit profile and tag check:
72
71
  V7L2–V7L5 require `0x61000001`, V7L6/V7L7 require `0x61000002`, and V8 profiles
73
72
  require `0x61000003`. Unknown layouts stop with source ranges and diagnostics.
@@ -1,11 +1,11 @@
1
1
  # Resource preview and GLB
2
2
 
3
3
  For files containing native boxes/cylinders, use the separate
4
- [native file viewer](viewer.md), added in version 0.3.0.
4
+ [native file viewer](viewer.md).
5
5
  It displays the native global frames and part tree without the preview extra.
6
6
 
7
- The preview API, introduced in 0.2.0, renders one selected embedded Parasolid resource and
8
- write a GLB plus an offline browser viewer. Install the optional dependencies:
7
+ The preview API renders one selected embedded Parasolid resource and writes
8
+ a GLB plus an offline browser viewer. Install the optional dependencies:
9
9
 
10
10
  ```sh
11
11
  python -m pip install 'icadkit[preview]'
@@ -1,7 +1,7 @@
1
1
  # Saved final bodies
2
2
 
3
- Version 0.3.5 supports qualified V7L6/V7L7 and V8L1/V8L2/V8L3 display paths using saved final
4
- B-Rep solids. This displays the saved result without replaying feature history.
3
+ The saved-body viewer supports qualified V7L6/V7L7 and V8L1/V8L2/V8L3 display
4
+ paths using saved final B-Rep solids. This displays the saved result without replaying feature history.
5
5
  It is separate from `--csg` and does not claim support for unknown CSG operations.
6
6
 
7
7
  ```sh
@@ -102,7 +102,7 @@ containing those surfaces. Faces require explicit boundary loops. A conical
102
102
  face that ends in its apex is stored with a loop of one vertex and no edge; the
103
103
  adapter closes it with one degenerated boundary edge when that vertex lies at
104
104
  the cone's apex. Vertex loops elsewhere, on other surfaces, or as a face's only
105
- loop remain unsupported (`saved.half_edge`); version 0.3.7 also closes
105
+ loop remain unsupported (`saved.half_edge`); the adapter also closes
106
106
  an apple, horn or lemon torus at its axis point the same way, with one
107
107
  degenerated edge per axis point. Intersection curves are rebuilt
108
108
  by the pinned adapter from their two support surfaces and saved chart points;
@@ -126,17 +126,15 @@ unqualified resource layouts, implicit external-file loading and complete featur
126
126
  history remain unsupported. Existing `--csg` evaluation remains separately scoped.
127
127
 
128
128
  An exact built-in schema profile can still lack a base type required by a
129
- resource. Such resources need the explicitly matching catalog. Version 0.3.0
130
- uses `parasolid-core 0.3.1` and exact V34 profile revision 2, which adds
131
- TORUS (54): qualified trimmed-torus and swept-arc solids no longer require a
132
- catalog. Other uncompiled types retain a diagnostic when no catalog is supplied.
133
- Catalogs are not bundled.
134
-
135
- Version 0.3.5 uses `parasolid-core 0.3.5`, which also supplies reviewed
136
- B-Rep mappings for [twenty-six further schema keys](support.md#schemas). This
137
- removes their catalog requirement within the qualified subsets. Since
138
- version 0.3.6 the backend maps SPUN_SURF as a surface of revolution; the
139
- adapter admits spun faces, closing a profile end on the spin axis with one
129
+ resource. Such resources need the explicitly matching catalog. The exact V34
130
+ profile includes TORUS (54): qualified trimmed-torus and swept-arc solids do not
131
+ require a catalog. Other uncompiled types retain a diagnostic when no catalog
132
+ is supplied. Catalogs are not bundled.
133
+
134
+ The pinned `parasolid-core` backend supplies reviewed B-Rep mappings for
135
+ [the built-in schema keys](support.md#schemas), allowing catalog-free reads
136
+ within their qualified subsets. The backend maps SPUN_SURF as a surface of
137
+ revolution; the adapter admits spun faces, closing a profile end on the spin axis with one
140
138
  degenerated edge like a cone apex
141
139
  (`degenerated_spun_axis_boundary`), see the
142
140
  [roadmap](roadmap.md#version-036-spun-surfaces). Offset surfaces are read but
@@ -196,6 +194,8 @@ unqualified, so bodies under a mirrored owner are not bound there.
196
194
 
197
195
  ## Local evidence for bindings and conversion
198
196
 
197
+ The conversion results below are historical measurements for the named releases.
198
+
199
199
  In a local sample of 305 V8 files with numbered resources, every one of 28,685
200
200
  indexed resources is named by an association record and every final marker has
201
201
  exactly one; 27,118 marker frames equal their association frames byte for byte,
@@ -205,8 +205,8 @@ bind and 2,670 bodies now bind to a different resource. For every one of 6,059
205
205
  evaluated bodies the saved [per-entity box](trailer.md) contains the solid in
206
206
  its local frame, and it is tight for 6,040 of them.
207
207
 
208
- Of 29,703 distinct bound resources in the sample, 27,093 convert to valid
209
- solids. An explicit schema catalog is needed only where no built-in profile
208
+ The version 0.3.5 checks convert 27,093 of the sample's 29,703 distinct bound
209
+ resources to valid solids. An explicit schema catalog is needed only where no built-in profile
210
210
  applies: for six of these resources, compared with 27,796 under core 0.3.3.
211
211
  Results agree with the catalog path, except that 253 resources whose line trims
212
212
  store unset parameters are now mapped; 168 of them convert. The others keep