icadkit 0.3.5__tar.gz → 0.3.7__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.
- {icadkit-0.3.5 → icadkit-0.3.7}/Cargo.lock +4 -4
- {icadkit-0.3.5 → icadkit-0.3.7}/Cargo.toml +2 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/LICENSES/rust-dependencies.txt +1 -1
- {icadkit-0.3.5 → icadkit-0.3.7}/PKG-INFO +28 -27
- {icadkit-0.3.5 → icadkit-0.3.7}/README.md +26 -25
- {icadkit-0.3.5 → icadkit-0.3.7}/THIRD_PARTY_NOTICES.md +7 -5
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/LICENSE +9 -7
- icadkit-0.3.7/crates/icad-core/build.rs +49 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/document.rs +13 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/lib.rs +3 -3
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/native.rs +93 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/trailer.rs +294 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/tests/resources.rs +32 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/LICENSE +9 -7
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/src/brep.rs +19 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/src/document.rs +77 -33
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/api.md +3 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/changelog.md +156 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/csg.md +17 -3
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/native.md +3 -1
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/preview.md +5 -3
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/roadmap.md +98 -3
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/saved-bodies.md +36 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/support.md +16 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/trailer.md +53 -3
- {icadkit-0.3.5 → icadkit-0.3.7}/pyproject.toml +1 -1
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/check_license.py +54 -11
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/verify_artifacts.py +11 -15
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/verify_install.py +1 -7
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/__init__.py +4 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_core.pyi +15 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_csg_occt.py +70 -5
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_preview_bridge.py +42 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_saved_occt.py +116 -28
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/csg.py +90 -19
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/preview.py +3 -9
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/trailer.py +81 -7
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/viewer.py +6 -6
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/saved_fixtures.py +156 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_api.py +2 -1
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_cli.py +1 -1
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_csg.py +143 -6
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_distribution.py +4 -2
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_geometry.py +19 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_preview.py +2 -10
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_saved.py +83 -6
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_trailer.py +147 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/trailer_fixtures.py +16 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/uv.lock +8 -8
- {icadkit-0.3.5 → icadkit-0.3.7}/COMMERCIAL-LICENSE.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/LICENSE +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/LICENSES/Apache-2.0.txt +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/LICENSES/PolyForm-Noncommercial-1.0.0.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/LICENSES/parasolid-core-MIT.txt +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/corpus/README.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/corpus/generate.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/corpus/public.jsonl +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/Cargo.toml +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/compression.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/error.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/header.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/limits.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/parasolid.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/parts.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/provenance.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/reader.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/record.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/resource.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/schema.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/src/views.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-core/tests/header.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/Cargo.toml +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/src/geometry.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/src/lib.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/crates/icad-python/src/schema.rs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/drawing.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/license.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/parameters.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/parts.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/references.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/docs/viewer.md +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/check_public_tree.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/test_publication.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/verify_corpus.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/scripts/verify_native_corpus.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/__main__.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_viewer/index.html +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_viewer/viewer.css +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_viewer/viewer.js +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/_viewer_io.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/api.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/cli.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/document.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/drawing.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/errors.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/geometry.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/models.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/native.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/parameters.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/parts.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/py.typed +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/references.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/saved.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/schema.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/src/icadkit/views.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/conftest.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/drawing_fixtures.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/fixture_builders.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/geometry_fixtures.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/parameter_fixtures.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/part_fixtures.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/preview_fixtures.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_corpus.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_drawing.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_extrusion.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_followup_parts.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_inspect.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_legacy_parts.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_mirrors.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_native.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_native_corpus.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_native_round.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_parameters.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_part_profiles.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_part_semantics.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_parts.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_profile_shapes.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_references.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_resource_cli.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_resources.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_v7_parts.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_v8l4_boundary.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_version_geometry.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/test_viewer.py +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/viewer_assembly_browser.mjs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/viewer_browser.mjs +0 -0
- {icadkit-0.3.5 → icadkit-0.3.7}/tests/viewer_mirror_browser.mjs +0 -0
|
@@ -89,7 +89,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
|
89
89
|
|
|
90
90
|
[[package]]
|
|
91
91
|
name = "icad-core"
|
|
92
|
-
version = "0.3.
|
|
92
|
+
version = "0.3.7"
|
|
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.
|
|
102
|
+
version = "0.3.7"
|
|
103
103
|
dependencies = [
|
|
104
104
|
"icad-core",
|
|
105
105
|
"parasolid-core",
|
|
@@ -142,9 +142,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
|
142
142
|
|
|
143
143
|
[[package]]
|
|
144
144
|
name = "parasolid-core"
|
|
145
|
-
version = "0.3.
|
|
145
|
+
version = "0.3.7"
|
|
146
146
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
147
|
-
checksum = "
|
|
147
|
+
checksum = "7ff3cbb9817406ac809cd989e47454deee4af89a30b57b436561b676f98af37e"
|
|
148
148
|
|
|
149
149
|
[[package]]
|
|
150
150
|
name = "portable-atomic"
|
|
@@ -3,13 +3,13 @@ members = ["crates/icad-core", "crates/icad-python"]
|
|
|
3
3
|
resolver = "3"
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.3.
|
|
6
|
+
version = "0.3.7"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
rust-version = "1.88"
|
|
9
9
|
license = "PolyForm-Noncommercial-1.0.0"
|
|
10
10
|
|
|
11
11
|
[workspace.dependencies]
|
|
12
|
-
parasolid-core = "=0.3.
|
|
12
|
+
parasolid-core = "=0.3.7"
|
|
13
13
|
pyo3 = { version = "=0.29.2", features = ["abi3-py310"] }
|
|
14
14
|
flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
|
|
15
15
|
sha2 = "0.10"
|
|
@@ -134,7 +134,7 @@ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
134
134
|
DEALINGS IN THE SOFTWARE.
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
=== parasolid-core 0.3.
|
|
137
|
+
=== parasolid-core 0.3.7 (MIT AND Apache-2.0) ===
|
|
138
138
|
MIT License
|
|
139
139
|
|
|
140
140
|
Copyright (c) 2026 parasolid-kit contributors
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: icadkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.7
|
|
4
4
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
5
5
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
7
7
|
Classifier: Programming Language :: Rust
|
|
8
8
|
Classifier: Typing :: Typed
|
|
9
|
-
Requires-Dist: parasolid-kit[occt]==0.
|
|
9
|
+
Requires-Dist: parasolid-kit[occt]==0.3.7 ; extra == 'preview'
|
|
10
10
|
Provides-Extra: preview
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
License-File: COMMERCIAL-LICENSE.md
|
|
@@ -32,27 +32,27 @@ 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.
|
|
36
|
-
|
|
37
|
-
- [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
Version **0.3.7** adds:
|
|
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
56
|
|
|
57
57
|
Version 0.3.0 added the [native file viewer](docs/viewer.md), broader
|
|
58
58
|
[part access](docs/parts.md), optional [V7L7 boolean evaluation](docs/csg.md)
|
|
@@ -73,7 +73,7 @@ The base reader supports standard GIL-enabled CPython 3.10–3.14. Wheel targets
|
|
|
73
73
|
are Linux x86_64 (glibc 2.28+), Windows x86_64 and macOS ARM64 (11+):
|
|
74
74
|
|
|
75
75
|
```sh
|
|
76
|
-
python -m pip install icadkit
|
|
76
|
+
python -m pip install icadkit
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
The native extension bundles `parasolid-core` and has no mandatory Python
|
|
@@ -82,7 +82,7 @@ explicit compatible catalog is needed only for schemas absent from the built-in
|
|
|
82
82
|
profiles. Release files are available on the
|
|
83
83
|
[GitHub releases page](https://github.com/monozukuri-ai/icadkit/releases).
|
|
84
84
|
|
|
85
|
-
For preview/GLB, install `python -m pip install 'icadkit[preview]
|
|
85
|
+
For preview/GLB, install `python -m pip install 'icadkit[preview]'`.
|
|
86
86
|
The optional OCCT dependency requires glibc 2.31+ on Linux; see
|
|
87
87
|
[preview requirements](docs/preview.md#dependencies-and-validation).
|
|
88
88
|
To build from a source checkout or sdist, install Rust 1.88+ and a C linker,
|
|
@@ -111,8 +111,9 @@ Qualified V7L7 part frames use millimetres and are evaluated relative to the
|
|
|
111
111
|
saved root frame. Qualified standalone primitive owners also expose geometry and saved
|
|
112
112
|
entity appearance. The separate [CSG API](docs/csg.md) and
|
|
113
113
|
`uv run --extra preview icadkit view model.icd --csg` evaluate qualified
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
unions, differences and intersections of boxes, cylinders, prisms and profile
|
|
115
|
+
extrusions, including saved single-leaf extrusion bodies. Unknown programs
|
|
116
|
+
retain diagnostics without substitute geometry.
|
|
116
117
|
The [saved final body mode](docs/saved-bodies.md), `view --saved-brep`, also
|
|
117
118
|
displays qualified V7L7/V8L3 final bodies and imported solids, including bounded
|
|
118
119
|
spherical, conical and toroidal surfaces. V8L3 resource sharing preserves each
|
|
@@ -4,27 +4,27 @@ 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.
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
Version **0.3.7** adds:
|
|
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
28
|
|
|
29
29
|
Version 0.3.0 added the [native file viewer](docs/viewer.md), broader
|
|
30
30
|
[part access](docs/parts.md), optional [V7L7 boolean evaluation](docs/csg.md)
|
|
@@ -45,7 +45,7 @@ The base reader supports standard GIL-enabled CPython 3.10–3.14. Wheel targets
|
|
|
45
45
|
are Linux x86_64 (glibc 2.28+), Windows x86_64 and macOS ARM64 (11+):
|
|
46
46
|
|
|
47
47
|
```sh
|
|
48
|
-
python -m pip install icadkit
|
|
48
|
+
python -m pip install icadkit
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
The native extension bundles `parasolid-core` and has no mandatory Python
|
|
@@ -54,7 +54,7 @@ explicit compatible catalog is needed only for schemas absent from the built-in
|
|
|
54
54
|
profiles. Release files are available on the
|
|
55
55
|
[GitHub releases page](https://github.com/monozukuri-ai/icadkit/releases).
|
|
56
56
|
|
|
57
|
-
For preview/GLB, install `python -m pip install 'icadkit[preview]
|
|
57
|
+
For preview/GLB, install `python -m pip install 'icadkit[preview]'`.
|
|
58
58
|
The optional OCCT dependency requires glibc 2.31+ on Linux; see
|
|
59
59
|
[preview requirements](docs/preview.md#dependencies-and-validation).
|
|
60
60
|
To build from a source checkout or sdist, install Rust 1.88+ and a C linker,
|
|
@@ -83,8 +83,9 @@ Qualified V7L7 part frames use millimetres and are evaluated relative to the
|
|
|
83
83
|
saved root frame. Qualified standalone primitive owners also expose geometry and saved
|
|
84
84
|
entity appearance. The separate [CSG API](docs/csg.md) and
|
|
85
85
|
`uv run --extra preview icadkit view model.icd --csg` evaluate qualified
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
unions, differences and intersections of boxes, cylinders, prisms and profile
|
|
87
|
+
extrusions, including saved single-leaf extrusion bodies. Unknown programs
|
|
88
|
+
retain diagnostics without substitute geometry.
|
|
88
89
|
The [saved final body mode](docs/saved-bodies.md), `view --saved-brep`, also
|
|
89
90
|
displays qualified V7L7/V8L3 final bodies and imported solids, including bounded
|
|
90
91
|
spherical, conical and toroidal surfaces. V8L3 resource sharing preserves each
|
|
@@ -4,8 +4,9 @@ icadkit project material is offered under PolyForm Noncommercial 1.0.0, with sep
|
|
|
4
4
|
commercial licensing available from UnRobotics Inc.
|
|
5
5
|
See `LICENSE` and `COMMERCIAL-LICENSE.md`.
|
|
6
6
|
|
|
7
|
-
Binary distributions also contain `parasolid-core
|
|
8
|
-
|
|
7
|
+
Binary distributions also contain `parasolid-core` (MIT AND Apache-2.0; the
|
|
8
|
+
exact version is listed in `LICENSES/rust-dependencies.txt`) and PyO3 (MIT OR
|
|
9
|
+
Apache-2.0, MIT selected). The source metadata declares
|
|
9
10
|
`PolyForm-Noncommercial-1.0.0`; the combined Python distribution declares
|
|
10
11
|
`PolyForm-Noncommercial-1.0.0 AND MIT AND Apache-2.0`. These expressions describe
|
|
11
12
|
different portions of the package, not a choice to use all icadkit material
|
|
@@ -25,9 +26,10 @@ under MIT or Apache-2.0. Third-party components are not relicensed.
|
|
|
25
26
|
for project-authored material. Their V30 scalar layouts derive from the
|
|
26
27
|
MIT/Apache-2.0 `parasolid-core` profile; see `tests/geometry_fixtures.py`
|
|
27
28
|
for attribution.
|
|
28
|
-
- The optional `preview` extra installs `parasolid-kit[occt]
|
|
29
|
-
|
|
30
|
-
the icadkit wheel. Their own
|
|
29
|
+
- The optional `preview` extra installs the `parasolid-kit[occt]` release
|
|
30
|
+
pinned in `pyproject.toml` and its separately distributed OCCT runtime
|
|
31
|
+
dependencies. These are not bundled in the icadkit wheel. Their own
|
|
32
|
+
distributions retain their license terms.
|
|
31
33
|
Generated viewer directories copy that package's browser assets and retain
|
|
32
34
|
the included MIT/Zlib notices and the n8ao ISC metadata / CC0-1.0 license-text
|
|
33
35
|
discrepancy. Keep those notices when redistributing generated viewers.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Generated by scripts/check_license.py --write
|
|
1
|
+
Generated by scripts/check_license.py --write.
|
|
2
2
|
Canonical source notices follow; paths refer to the source root.
|
|
3
3
|
|
|
4
4
|
===== LICENSE =====
|
|
@@ -108,8 +108,9 @@ icadkit project material is offered under PolyForm Noncommercial 1.0.0, with sep
|
|
|
108
108
|
commercial licensing available from UnRobotics Inc.
|
|
109
109
|
See `LICENSE` and `COMMERCIAL-LICENSE.md`.
|
|
110
110
|
|
|
111
|
-
Binary distributions also contain `parasolid-core
|
|
112
|
-
|
|
111
|
+
Binary distributions also contain `parasolid-core` (MIT AND Apache-2.0; the
|
|
112
|
+
exact version is listed in `LICENSES/rust-dependencies.txt`) and PyO3 (MIT OR
|
|
113
|
+
Apache-2.0, MIT selected). The source metadata declares
|
|
113
114
|
`PolyForm-Noncommercial-1.0.0`; the combined Python distribution declares
|
|
114
115
|
`PolyForm-Noncommercial-1.0.0 AND MIT AND Apache-2.0`. These expressions describe
|
|
115
116
|
different portions of the package, not a choice to use all icadkit material
|
|
@@ -129,9 +130,10 @@ under MIT or Apache-2.0. Third-party components are not relicensed.
|
|
|
129
130
|
for project-authored material. Their V30 scalar layouts derive from the
|
|
130
131
|
MIT/Apache-2.0 `parasolid-core` profile; see `tests/geometry_fixtures.py`
|
|
131
132
|
for attribution.
|
|
132
|
-
- The optional `preview` extra installs `parasolid-kit[occt]
|
|
133
|
-
|
|
134
|
-
the icadkit wheel. Their own
|
|
133
|
+
- The optional `preview` extra installs the `parasolid-kit[occt]` release
|
|
134
|
+
pinned in `pyproject.toml` and its separately distributed OCCT runtime
|
|
135
|
+
dependencies. These are not bundled in the icadkit wheel. Their own
|
|
136
|
+
distributions retain their license terms.
|
|
135
137
|
Generated viewer directories copy that package's browser assets and retain
|
|
136
138
|
the included MIT/Zlib notices and the n8ao ISC metadata / CC0-1.0 license-text
|
|
137
139
|
discrepancy. Keep those notices when redistributing generated viewers.
|
|
@@ -582,7 +584,7 @@ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
582
584
|
DEALINGS IN THE SOFTWARE.
|
|
583
585
|
|
|
584
586
|
|
|
585
|
-
=== parasolid-core 0.3.
|
|
587
|
+
=== parasolid-core 0.3.7 (MIT AND Apache-2.0) ===
|
|
586
588
|
MIT License
|
|
587
589
|
|
|
588
590
|
Copyright (c) 2026 parasolid-kit contributors
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//! Records the resolved `parasolid-core` version from the workspace lock file.
|
|
2
|
+
//!
|
|
3
|
+
//! The crate reports which backend release it was compiled with
|
|
4
|
+
//! (`PARASOLID_CORE_VERSION`). Reading it from `Cargo.lock` keeps the manifest
|
|
5
|
+
//! pin the only place in the source that names that version.
|
|
6
|
+
|
|
7
|
+
use std::env;
|
|
8
|
+
use std::fs;
|
|
9
|
+
use std::path::{Path, PathBuf};
|
|
10
|
+
|
|
11
|
+
fn main() -> Result<(), String> {
|
|
12
|
+
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").ok_or("CARGO_MANIFEST_DIR is not set")?;
|
|
13
|
+
let lock = PathBuf::from(manifest_dir)
|
|
14
|
+
.ancestors()
|
|
15
|
+
.map(|dir| dir.join("Cargo.lock"))
|
|
16
|
+
.find(|path| path.is_file())
|
|
17
|
+
.ok_or("no Cargo.lock above the crate directory")?;
|
|
18
|
+
let version = resolved_version(&lock, "parasolid-core")?;
|
|
19
|
+
println!("cargo:rerun-if-changed={}", lock.display());
|
|
20
|
+
println!("cargo:rustc-env=ICAD_PARASOLID_CORE_VERSION={version}");
|
|
21
|
+
Ok(())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// The version of `package` in the lock file, which must resolve it exactly once.
|
|
25
|
+
fn resolved_version(lock: &Path, package: &str) -> Result<String, String> {
|
|
26
|
+
let text = fs::read_to_string(lock)
|
|
27
|
+
.map_err(|error| format!("cannot read {}: {error}", lock.display()))?;
|
|
28
|
+
let mut versions = Vec::new();
|
|
29
|
+
let mut name = None;
|
|
30
|
+
for line in text.lines().map(str::trim) {
|
|
31
|
+
if line == "[[package]]" {
|
|
32
|
+
name = None;
|
|
33
|
+
} else if let Some(value) = line.strip_prefix("name = ") {
|
|
34
|
+
name = Some(value.trim_matches('"'));
|
|
35
|
+
} else if let Some(value) = line.strip_prefix("version = ")
|
|
36
|
+
&& name == Some(package)
|
|
37
|
+
{
|
|
38
|
+
versions.push(value.trim_matches('"').to_owned());
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
match versions.as_slice() {
|
|
42
|
+
[version] => Ok(version.clone()),
|
|
43
|
+
[] => Err(format!("{package} is not resolved in {}", lock.display())),
|
|
44
|
+
_ => Err(format!(
|
|
45
|
+
"{package} resolves to several versions in {}",
|
|
46
|
+
lock.display()
|
|
47
|
+
)),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -592,4 +592,17 @@ impl Document {
|
|
|
592
592
|
self.limits.resource(range.end - range.start, range.start)?;
|
|
593
593
|
Ok(&self.data[range.start as usize..range.end as usize])
|
|
594
594
|
}
|
|
595
|
+
|
|
596
|
+
/// Decode one saved boolean component record in place, without an owner
|
|
597
|
+
/// context. The caller has already framed the record and checks its saved
|
|
598
|
+
/// program, result backlink and root frame.
|
|
599
|
+
pub fn read_component(
|
|
600
|
+
&self,
|
|
601
|
+
range: ByteRange,
|
|
602
|
+
) -> Result<crate::native::NativeEntityRecord, InspectError> {
|
|
603
|
+
Ok(crate::native::read_component_entity(
|
|
604
|
+
self.source_bytes(range)?,
|
|
605
|
+
range,
|
|
606
|
+
))
|
|
607
|
+
}
|
|
595
608
|
}
|
|
@@ -38,7 +38,7 @@ pub use resource::{Encoding, ResourceAssociation, ResourceRef};
|
|
|
38
38
|
pub use schema::SchemaCatalog;
|
|
39
39
|
pub use trailer::{
|
|
40
40
|
TrailerBlock, TrailerBlockData, TrailerEdge, TrailerFace, TrailerIndex, TrailerLimits,
|
|
41
|
-
TrailerTable, TrailerView,
|
|
41
|
+
TrailerParameterLine, TrailerSurface, TrailerTable, TrailerView,
|
|
42
42
|
};
|
|
43
43
|
pub use views::{ViewEntry, ViewIndex, ViewLimits, ViewRecord};
|
|
44
44
|
|
|
@@ -47,8 +47,8 @@ use parasolid_core::{BuiltinProfileRegistry, ParseError};
|
|
|
47
47
|
/// Version of this Rust crate, in Cargo SemVer notation.
|
|
48
48
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
49
49
|
|
|
50
|
-
///
|
|
51
|
-
pub const PARASOLID_CORE_VERSION: &str = "
|
|
50
|
+
/// Resolved registry version of the backend, read from `Cargo.lock` at build time.
|
|
51
|
+
pub const PARASOLID_CORE_VERSION: &str = env!("ICAD_PARASOLID_CORE_VERSION");
|
|
52
52
|
|
|
53
53
|
/// Metadata of the compiled Parasolid backend, not ICD format coverage.
|
|
54
54
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
@@ -139,6 +139,18 @@ pub(crate) fn read_parametric_entity(bytes: &[u8], byte_range: ByteRange) -> Nat
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
pub(crate) fn read_entity(bytes: &[u8], byte_range: ByteRange) -> NativeEntityRecord {
|
|
142
|
+
decode_entity(bytes, byte_range, false)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// A component record of a saved boolean body: the standalone layout with the
|
|
146
|
+
/// component bit set, an optional explicit-result bit, and a result backlink
|
|
147
|
+
/// where a standalone record stores zero. The caller checks that backlink and
|
|
148
|
+
/// the saved program; nothing here establishes a finished solid.
|
|
149
|
+
pub(crate) fn read_component_entity(bytes: &[u8], byte_range: ByteRange) -> NativeEntityRecord {
|
|
150
|
+
decode_entity(bytes, byte_range, true)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fn decode_entity(bytes: &[u8], byte_range: ByteRange, component: bool) -> NativeEntityRecord {
|
|
142
154
|
let mut result = undecoded_entity(bytes, byte_range);
|
|
143
155
|
// Layer, saved visibility and palette index are qualified only for these
|
|
144
156
|
// exact native layouts. A Parasolid body has a different attribute layout.
|
|
@@ -168,11 +180,18 @@ pub(crate) fn read_entity(bytes: &[u8], byte_range: ByteRange) -> NativeEntityRe
|
|
|
168
180
|
bytes.len() == length
|
|
169
181
|
&& word(bytes, 4) > 0
|
|
170
182
|
&& word(bytes, 8) == 0
|
|
171
|
-
&&
|
|
183
|
+
&& if component {
|
|
184
|
+
// Operands carry the component bit 0x20 and, under an explicit
|
|
185
|
+
// result marker, bit 0x100. The mirror bit stays separate.
|
|
186
|
+
word(bytes, 12) & 0x20 != 0
|
|
187
|
+
&& matches!(word(bytes, 12) & 0x00ffeedf, 0x000100c1 | 0x00010081)
|
|
188
|
+
} else {
|
|
189
|
+
matches!(word(bytes, 12) & 0x00ffefff, 0x000100c1 | 0x00010081)
|
|
190
|
+
}
|
|
172
191
|
&& word(bytes, 16) & 0xf0000000 == 0x80000000
|
|
173
192
|
&& word(bytes, 20) == 0
|
|
174
193
|
&& word(bytes, 24) == marker
|
|
175
|
-
&& word(bytes, 32) == 0
|
|
194
|
+
&& (component || word(bytes, 32) == 0)
|
|
176
195
|
// The upper word is retained as opaque producer metadata.
|
|
177
196
|
&& word(bytes, 40) & 0xffff == if kind == "polygon_extrusion" { 0x1b0 } else { 0x180 }
|
|
178
197
|
&& word(bytes, 44) == 0
|
|
@@ -623,3 +642,75 @@ fn simple_polygon(values: &[f64]) -> bool {
|
|
|
623
642
|
}
|
|
624
643
|
true
|
|
625
644
|
}
|
|
645
|
+
|
|
646
|
+
#[cfg(test)]
|
|
647
|
+
mod tests {
|
|
648
|
+
use super::*;
|
|
649
|
+
|
|
650
|
+
/// A closed rectangle profile of five straight elements with a flag trailer.
|
|
651
|
+
fn record(flags: u32, backlink: u32) -> Vec<u8> {
|
|
652
|
+
let mut bytes = vec![0_u8; 216];
|
|
653
|
+
for (at, value) in [
|
|
654
|
+
(0, 216_u32),
|
|
655
|
+
(4, 1),
|
|
656
|
+
(12, 76 << 24 | flags),
|
|
657
|
+
(16, 0x8000_0003),
|
|
658
|
+
(24, 0x5944_00c0),
|
|
659
|
+
(32, backlink),
|
|
660
|
+
(40, 0x180),
|
|
661
|
+
] {
|
|
662
|
+
bytes[at..at + 4].copy_from_slice(&value.to_le_bytes());
|
|
663
|
+
}
|
|
664
|
+
bytes[29] = 0x11;
|
|
665
|
+
let values: [f64; 20] = [
|
|
666
|
+
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 13.0, 0.0, 0.0, 10.0, 0.0, 10.0, 5.0, 0.0,
|
|
667
|
+
5.0, 0.0, 0.0,
|
|
668
|
+
];
|
|
669
|
+
for (i, value) in values.iter().enumerate() {
|
|
670
|
+
bytes[48 + 8 * i..56 + 8 * i].copy_from_slice(&value.to_le_bytes());
|
|
671
|
+
}
|
|
672
|
+
bytes
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const RANGE: ByteRange = ByteRange {
|
|
676
|
+
start: 1000,
|
|
677
|
+
end: 1216,
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
fn decoded(entity: &NativeEntityRecord) -> Option<(&'static str, usize)> {
|
|
681
|
+
entity
|
|
682
|
+
.primitive
|
|
683
|
+
.as_ref()
|
|
684
|
+
.map(|p| (p.kind, p.parameters.len()))
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
#[test]
|
|
688
|
+
fn component_flags_select_the_reader() {
|
|
689
|
+
let implicit = record(0x100e1, 0);
|
|
690
|
+
assert!(read_entity(&implicit, RANGE).primitive.is_none());
|
|
691
|
+
assert_eq!(
|
|
692
|
+
read_entity(&implicit, RANGE).diagnostics[0].code,
|
|
693
|
+
"native.layout"
|
|
694
|
+
);
|
|
695
|
+
let component = read_component_entity(&implicit, RANGE);
|
|
696
|
+
assert_eq!(decoded(&component), Some(("profile_extrusion", 29)));
|
|
697
|
+
assert_eq!(component.source_id, Some(0x8000_0003));
|
|
698
|
+
assert_eq!(component.is_mirror, Some(false));
|
|
699
|
+
// An explicit component keeps its result backlink; a standalone record
|
|
700
|
+
// with the same word, or without the component bit, is not an operand.
|
|
701
|
+
let explicit = record(0x101e1, 0x8000_0009);
|
|
702
|
+
assert_eq!(
|
|
703
|
+
decoded(&read_component_entity(&explicit, RANGE)),
|
|
704
|
+
Some(("profile_extrusion", 29))
|
|
705
|
+
);
|
|
706
|
+
assert!(read_entity(&explicit, RANGE).primitive.is_none());
|
|
707
|
+
assert!(read_entity(&record(0x100c1, 1), RANGE).primitive.is_none());
|
|
708
|
+
let standalone = read_component_entity(&record(0x100c1, 0), RANGE);
|
|
709
|
+
assert!(standalone.primitive.is_none());
|
|
710
|
+
assert_eq!(standalone.diagnostics[0].code, "native.layout");
|
|
711
|
+
assert_eq!(
|
|
712
|
+
decoded(&read_entity(&record(0x100c1, 0), RANGE)),
|
|
713
|
+
Some(("profile_extrusion", 29))
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
}
|