parasolid-kit 0.1.0.dev3__tar.gz → 0.1.0.dev4__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.
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/Cargo.lock +2 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/Cargo.toml +1 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/PKG-INFO +21 -12
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/README.md +20 -11
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/brep/mapper.rs +249 -62
- parasolid_kit-0.1.0.dev4/crates/parasolid-core/src/brep/profile_roles.rs +680 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/error.rs +6 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/lib.rs +1 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/mod.rs +3 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/profile.rs +84 -6
- parasolid_kit-0.1.0.dev4/crates/parasolid-core/src/schema/profiles/mod.rs +10 -0
- parasolid_kit-0.1.0.dev4/crates/parasolid-core/src/schema/profiles/sch13006.rs +447 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/profiles/sch30000.rs +42 -5
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/provider.rs +57 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/registry.rs +3 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/text_document.rs +3 -3
- parasolid_kit-0.1.0.dev4/crates/parasolid-core/tests/builtin_sch13006.rs +147 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/tests/builtin_sch30000.rs +66 -7
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/tests/builtin_sch30000_brep.rs +68 -3
- parasolid_kit-0.1.0.dev4/crates/parasolid-core/tests/embedded_base_membership.rs +303 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/tests/support/sch30000.rs +30 -4
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/docs/api.md +18 -8
- parasolid_kit-0.1.0.dev4/docs/builtin-profiles.md +607 -0
- parasolid_kit-0.1.0.dev4/docs/doubly-periodic-surface-evidence.json +293 -0
- parasolid_kit-0.1.0.dev4/docs/doubly-periodic-surface-evidence.md +120 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/docs/format-support.md +78 -10
- parasolid_kit-0.1.0.dev4/docs/nurbs-surface-evidence.json +489 -0
- parasolid_kit-0.1.0.dev4/docs/nurbs-surface-evidence.md +136 -0
- parasolid_kit-0.1.0.dev4/docs/rational-periodic-surface-evidence.json +290 -0
- parasolid_kit-0.1.0.dev4/docs/rational-periodic-surface-evidence.md +113 -0
- parasolid_kit-0.1.0.dev4/docs/step-accuracy-data.json +266 -0
- parasolid_kit-0.1.0.dev4/docs/step-accuracy.md +176 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/fuzz/Cargo.lock +1 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/pyproject.toml +1 -1
- parasolid_kit-0.1.0.dev4/scripts/prepare_fuzz_corpus.py +169 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_artifacts.py +3 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_isolated_install.py +44 -15
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_optional_install.py +2 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/__init__.py +1 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/_native.py +10 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/schema/model.py +1 -2
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_artifact_gate.py +5 -5
- parasolid_kit-0.1.0.dev4/tests/test_builtin_bspline_surface_runtime.py +160 -0
- parasolid_kit-0.1.0.dev4/tests/test_builtin_cone_runtime.py +102 -0
- parasolid_kit-0.1.0.dev4/tests/test_builtin_embedded_runtime.py +182 -0
- parasolid_kit-0.1.0.dev4/tests/test_builtin_intersection_data_runtime.py +191 -0
- parasolid_kit-0.1.0.dev4/tests/test_builtin_intersection_runtime.py +200 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_builtin_schema_runtime.py +3 -3
- parasolid_kit-0.1.0.dev4/tests/test_builtin_spcurve_runtime.py +378 -0
- parasolid_kit-0.1.0.dev4/tests/test_builtin_trimmed_runtime.py +212 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_distribution_runtime.py +26 -1
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_public_contracts.py +2 -2
- parasolid_kit-0.1.0.dev3/crates/parasolid-core/src/brep/profile_roles.rs +0 -255
- parasolid_kit-0.1.0.dev3/crates/parasolid-core/src/schema/profiles/mod.rs +0 -5
- parasolid_kit-0.1.0.dev3/docs/builtin-profiles.md +0 -95
- parasolid_kit-0.1.0.dev3/scripts/prepare_fuzz_corpus.py +0 -74
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/.gitattributes +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/LICENSE +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/corpus/README.md +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/corpus/manifest.schema.json +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/Cargo.toml +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/brep/metrics.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/brep/mod.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/brep/model.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/comparison.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/document.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/header.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/reader.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/catalog.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/coverage.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/decoder.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/model.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/schema/wire.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/text_reader.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/user_fields.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/tests/builtin_sch30000_holdout_values.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-python/Cargo.toml +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-python/src/brep.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-python/src/lib.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/fuzz/Cargo.toml +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/fuzz/fuzz_targets/inspect.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/fuzz/fuzz_targets/parse.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/fuzz/fuzz_targets/schema_catalog.rs +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_corpus.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_optional_interop_i0.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_optional_interop_i5.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_optional_interop_i6.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/scripts/verify_optional_interop_i7.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/__main__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/api.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/binary/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/binary/document.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/binary/header.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/brep/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/brep/_native.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/brep/geometry.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/brep/model.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/brep/topology.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/cli.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/diagnostics.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/errors.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/_typing.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/cadquery.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/dependency.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/errors.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/limits.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/conversion.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/coverage.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/geometry.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/model.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/options.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/step.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/topology.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/occt/validation.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/glb.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/model.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/server.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/static/index.html +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/static/viewer.css +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/static/viewer.js +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/tessellation.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/interop/preview/writer.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/limits.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/py.typed +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/schema/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/schema/api.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/schema/provider.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/summary.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/text/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/text/header.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/validation/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/src/parasolid_kit/validation/comparison.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/_occt_fixtures.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/support/__init__.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/support/parasolid_binary.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/support/parasolid_schema.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/support/parasolid_text.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_brep.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_cadquery_adapter.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_cli.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_corpus_gate.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_corpus_manifest.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_diagnostics.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_geometry_coverage.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_inspect_xb.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_interop.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_limits.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_occt_conversion.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_parse_xb.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_parse_xt.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_preview.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_schema_catalog.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_schema_resolution.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_step_export.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_summary.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_synthetic_binary.py +0 -0
- {parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/tests/test_user_fields.py +0 -0
|
@@ -88,7 +88,7 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
|
88
88
|
|
|
89
89
|
[[package]]
|
|
90
90
|
name = "parasolid-core"
|
|
91
|
-
version = "0.1.0-
|
|
91
|
+
version = "0.1.0-dev4"
|
|
92
92
|
dependencies = [
|
|
93
93
|
"serde_json",
|
|
94
94
|
"sha2",
|
|
@@ -96,7 +96,7 @@ dependencies = [
|
|
|
96
96
|
|
|
97
97
|
[[package]]
|
|
98
98
|
name = "parasolid-python"
|
|
99
|
-
version = "0.1.0-
|
|
99
|
+
version = "0.1.0-dev4"
|
|
100
100
|
dependencies = [
|
|
101
101
|
"parasolid-core",
|
|
102
102
|
"pyo3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parasolid-kit
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev4
|
|
4
4
|
Classifier: Development Status :: 2 - Pre-Alpha
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -70,7 +70,7 @@ The `--pre` option is required while only development releases are available.
|
|
|
70
70
|
To install the current release by exact version instead:
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
-
python -m pip install "parasolid-kit==0.1.0.
|
|
73
|
+
python -m pip install "parasolid-kit==0.1.0.dev4"
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Stable releases, once available, can be installed without `--pre`:
|
|
@@ -82,14 +82,14 @@ python -m pip install parasolid-kit
|
|
|
82
82
|
Alternatively, install a downloaded wheel directly:
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
|
-
python -m pip install /path/to/parasolid_kit-0.1.0.
|
|
85
|
+
python -m pip install /path/to/parasolid_kit-0.1.0.dev4-cp310-abi3-PLATFORM.whl
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Header inspection works immediately after installation. Complete parsing and
|
|
89
89
|
B-Rep checking also work without a schema file for the built-in
|
|
90
90
|
`SCH_3000000_30000` profile (`verified_subset`): Onshape V30 text/neutral binary
|
|
91
|
-
exports of single solid boxes, prisms, cylinders,
|
|
92
|
-
user fields. Other keys and uncovered types require an explicit provider; see
|
|
91
|
+
exports of single solid boxes, prisms, cylinders, through-holes, spheres, and
|
|
92
|
+
verified solids with elliptical edges, with zero user fields. Other keys and uncovered types require an explicit provider; see
|
|
93
93
|
[Schema catalogs](#schema-catalogs). STEP, CadQuery, and preview operations also
|
|
94
94
|
require an optional runtime and geometry supported by that adapter.
|
|
95
95
|
|
|
@@ -235,14 +235,23 @@ python -m pip install .
|
|
|
235
235
|
|
|
236
236
|
## Schema catalogs
|
|
237
237
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
internal key is exactly `SCH_3000000_30000`. It needs no catalog, network, or
|
|
241
|
-
CAD installation at runtime. [Profile provenance and coverage](docs/builtin-profiles.md)
|
|
242
|
-
records its source, canonical hash, and validation scope.
|
|
238
|
+
When neither a provider nor a schema directory is supplied, default parsing
|
|
239
|
+
selects one of these compiled profiles by the exact internal stream key:
|
|
243
240
|
|
|
244
|
-
|
|
245
|
-
|
|
241
|
+
| Internal schema key | Built-in profile | Reviewed base layout |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| `SCH_3000000_30000` | `onshape-sch30000-r2` | Onshape V30, 24 types / 202 field groups |
|
|
244
|
+
| `SCH_1300000_13006` | `onshape-sch13006-r6` | Onshape V13, 40 types / 327 field groups |
|
|
245
|
+
| `SCH_3000310_30000_13006` | `icad-sch30000-13006-r5` | 13006 base plus trimmed curve (133): 30 types / 240 groups; embedded edits and full type 204 |
|
|
246
|
+
|
|
247
|
+
All have `verified_subset` coverage and require zero user fields. They need no
|
|
248
|
+
catalog, network, or CAD installation at runtime.
|
|
249
|
+
[Profile provenance and coverage](docs/builtin-profiles.md) records their sources,
|
|
250
|
+
canonical hashes, and validation limits. The iCAD profile accepts extracted
|
|
251
|
+
Parasolid streams; `.icd` container parsing remains outside this package.
|
|
252
|
+
|
|
253
|
+
Use an external catalog for other keys or types outside these subsets.
|
|
254
|
+
An explicit provider is authoritative: an
|
|
246
255
|
empty provider or missing exact catalog fails without switching to the built-in
|
|
247
256
|
profile. `schema_provider=None` means default selection. Nearby versions and
|
|
248
257
|
the human-readable X_T common-header `SCH` value are never used as substitutes.
|
|
@@ -46,7 +46,7 @@ The `--pre` option is required while only development releases are available.
|
|
|
46
46
|
To install the current release by exact version instead:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
python -m pip install "parasolid-kit==0.1.0.
|
|
49
|
+
python -m pip install "parasolid-kit==0.1.0.dev4"
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Stable releases, once available, can be installed without `--pre`:
|
|
@@ -58,14 +58,14 @@ python -m pip install parasolid-kit
|
|
|
58
58
|
Alternatively, install a downloaded wheel directly:
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
|
-
python -m pip install /path/to/parasolid_kit-0.1.0.
|
|
61
|
+
python -m pip install /path/to/parasolid_kit-0.1.0.dev4-cp310-abi3-PLATFORM.whl
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Header inspection works immediately after installation. Complete parsing and
|
|
65
65
|
B-Rep checking also work without a schema file for the built-in
|
|
66
66
|
`SCH_3000000_30000` profile (`verified_subset`): Onshape V30 text/neutral binary
|
|
67
|
-
exports of single solid boxes, prisms, cylinders,
|
|
68
|
-
user fields. Other keys and uncovered types require an explicit provider; see
|
|
67
|
+
exports of single solid boxes, prisms, cylinders, through-holes, spheres, and
|
|
68
|
+
verified solids with elliptical edges, with zero user fields. Other keys and uncovered types require an explicit provider; see
|
|
69
69
|
[Schema catalogs](#schema-catalogs). STEP, CadQuery, and preview operations also
|
|
70
70
|
require an optional runtime and geometry supported by that adapter.
|
|
71
71
|
|
|
@@ -211,14 +211,23 @@ python -m pip install .
|
|
|
211
211
|
|
|
212
212
|
## Schema catalogs
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
internal key is exactly `SCH_3000000_30000`. It needs no catalog, network, or
|
|
217
|
-
CAD installation at runtime. [Profile provenance and coverage](docs/builtin-profiles.md)
|
|
218
|
-
records its source, canonical hash, and validation scope.
|
|
214
|
+
When neither a provider nor a schema directory is supplied, default parsing
|
|
215
|
+
selects one of these compiled profiles by the exact internal stream key:
|
|
219
216
|
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
| Internal schema key | Built-in profile | Reviewed base layout |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| `SCH_3000000_30000` | `onshape-sch30000-r2` | Onshape V30, 24 types / 202 field groups |
|
|
220
|
+
| `SCH_1300000_13006` | `onshape-sch13006-r6` | Onshape V13, 40 types / 327 field groups |
|
|
221
|
+
| `SCH_3000310_30000_13006` | `icad-sch30000-13006-r5` | 13006 base plus trimmed curve (133): 30 types / 240 groups; embedded edits and full type 204 |
|
|
222
|
+
|
|
223
|
+
All have `verified_subset` coverage and require zero user fields. They need no
|
|
224
|
+
catalog, network, or CAD installation at runtime.
|
|
225
|
+
[Profile provenance and coverage](docs/builtin-profiles.md) records their sources,
|
|
226
|
+
canonical hashes, and validation limits. The iCAD profile accepts extracted
|
|
227
|
+
Parasolid streams; `.icd` container parsing remains outside this package.
|
|
228
|
+
|
|
229
|
+
Use an external catalog for other keys or types outside these subsets.
|
|
230
|
+
An explicit provider is authoritative: an
|
|
222
231
|
empty provider or missing exact catalog fails without switching to the built-in
|
|
223
232
|
profile. `schema_provider=None` means default selection. Nearby versions and
|
|
224
233
|
the human-readable X_T common-header `SCH` value are never used as substitutes.
|
{parasolid_kit-0.1.0.dev3 → parasolid_kit-0.1.0.dev4}/crates/parasolid-core/src/brep/mapper.rs
RENAMED
|
@@ -40,7 +40,11 @@ pub fn map_xb_brep_with_diagnostic_limit(
|
|
|
40
40
|
BrepSourceFormat::Binary,
|
|
41
41
|
document.schema_key.raw(),
|
|
42
42
|
&document.nodes,
|
|
43
|
-
RoleAccess::select(
|
|
43
|
+
RoleAccess::select(
|
|
44
|
+
&document.schema_provider,
|
|
45
|
+
document.schema_key.raw(),
|
|
46
|
+
&document.schemas,
|
|
47
|
+
)?,
|
|
44
48
|
)
|
|
45
49
|
.with_max_diagnostics(max_diagnostics)
|
|
46
50
|
.map()
|
|
@@ -71,7 +75,11 @@ pub fn map_xt_brep_with_diagnostic_limit(
|
|
|
71
75
|
BrepSourceFormat::Text,
|
|
72
76
|
document.schema_key.raw(),
|
|
73
77
|
&document.nodes,
|
|
74
|
-
RoleAccess::select(
|
|
78
|
+
RoleAccess::select(
|
|
79
|
+
&document.schema_provider,
|
|
80
|
+
document.schema_key.raw(),
|
|
81
|
+
&document.schemas,
|
|
82
|
+
)?,
|
|
75
83
|
)
|
|
76
84
|
.with_max_diagnostics(max_diagnostics)
|
|
77
85
|
.map()
|
|
@@ -472,40 +480,9 @@ impl<'a> Mapper<'a> {
|
|
|
472
480
|
transverse_radius: self.positive_double(node, "transverse_radius")?,
|
|
473
481
|
conjugate_radius: self.positive_double(node, "conjugate_radius")?,
|
|
474
482
|
},
|
|
475
|
-
"TRIMMED_CURVE" =>
|
|
476
|
-
basis_curve: self.required_id(
|
|
477
|
-
node,
|
|
478
|
-
"basis_curve",
|
|
479
|
-
"curve geometry",
|
|
480
|
-
&self.ids.curves,
|
|
481
|
-
)?,
|
|
482
|
-
start_point: self.vector(node, "point_1")?,
|
|
483
|
-
end_point: self.vector(node, "point_2")?,
|
|
484
|
-
start_parameter: self.double(node, "parm_1")?,
|
|
485
|
-
end_parameter: self.double(node, "parm_2")?,
|
|
486
|
-
},
|
|
483
|
+
"TRIMMED_CURVE" => self.trimmed_curve(node)?,
|
|
487
484
|
"B_CURVE" => CurveKind::Nurbs(self.nurbs_curve(node)?),
|
|
488
|
-
"SP_CURVE" =>
|
|
489
|
-
surface: self.required_id(
|
|
490
|
-
node,
|
|
491
|
-
"surface",
|
|
492
|
-
"surface geometry",
|
|
493
|
-
&self.ids.surfaces,
|
|
494
|
-
)?,
|
|
495
|
-
parameter_curve: self.required_id(
|
|
496
|
-
node,
|
|
497
|
-
"b_curve",
|
|
498
|
-
"curve geometry",
|
|
499
|
-
&self.ids.curves,
|
|
500
|
-
)?,
|
|
501
|
-
original_curve: self.optional_id(
|
|
502
|
-
node,
|
|
503
|
-
"original",
|
|
504
|
-
"curve geometry",
|
|
505
|
-
&self.ids.curves,
|
|
506
|
-
)?,
|
|
507
|
-
tolerance_to_original: self.optional_double(node, "tolerance_to_original")?,
|
|
508
|
-
},
|
|
485
|
+
"SP_CURVE" => self.surface_parametric_curve(node)?,
|
|
509
486
|
"INTERSECTION" => self.intersection_curve(node)?,
|
|
510
487
|
type_name => {
|
|
511
488
|
let source = self.source(node);
|
|
@@ -659,7 +636,70 @@ impl<'a> Mapper<'a> {
|
|
|
659
636
|
})
|
|
660
637
|
}
|
|
661
638
|
|
|
639
|
+
#[allow(clippy::float_cmp)] // Equal parameters are forbidden, however short a valid trim is.
|
|
640
|
+
fn trimmed_curve(&self, node: &RawNode) -> Result<CurveKind, ParseError> {
|
|
641
|
+
let basis_curve =
|
|
642
|
+
self.required_id(node, "basis_curve", "curve geometry", &self.ids.curves)?;
|
|
643
|
+
let basis_index = self.required_pointer(node, "basis_curve")?;
|
|
644
|
+
if basis_index == node.index {
|
|
645
|
+
return Err(self.invalid_geometry(
|
|
646
|
+
node,
|
|
647
|
+
"basis_curve",
|
|
648
|
+
"trimmed curve references itself",
|
|
649
|
+
));
|
|
650
|
+
}
|
|
651
|
+
if self.sense(node, "sense")? != Sense::Positive {
|
|
652
|
+
return Err(self.invalid_geometry(
|
|
653
|
+
node,
|
|
654
|
+
"sense",
|
|
655
|
+
"trimmed curve sense must be positive",
|
|
656
|
+
));
|
|
657
|
+
}
|
|
658
|
+
let start_parameter = self.double(node, "parm_1")?;
|
|
659
|
+
let end_parameter = self.double(node, "parm_2")?;
|
|
660
|
+
let basis_sense = self.sense(self.node(basis_index)?, "sense")?;
|
|
661
|
+
if start_parameter == end_parameter
|
|
662
|
+
|| (basis_sense == Sense::Positive && end_parameter < start_parameter)
|
|
663
|
+
|| (basis_sense == Sense::Negative && end_parameter > start_parameter)
|
|
664
|
+
{
|
|
665
|
+
return Err(self.invalid_geometry(
|
|
666
|
+
node,
|
|
667
|
+
"parm_2",
|
|
668
|
+
"trim parameters must be distinct and follow the basis curve sense",
|
|
669
|
+
));
|
|
670
|
+
}
|
|
671
|
+
Ok(CurveKind::Trimmed {
|
|
672
|
+
basis_curve,
|
|
673
|
+
start_point: self.vector(node, "point_1")?,
|
|
674
|
+
end_point: self.vector(node, "point_2")?,
|
|
675
|
+
start_parameter,
|
|
676
|
+
end_parameter,
|
|
677
|
+
})
|
|
678
|
+
}
|
|
679
|
+
|
|
662
680
|
fn intersection_curve(&self, node: &RawNode) -> Result<CurveKind, ParseError> {
|
|
681
|
+
let chart = self.required_typed_node(node, "chart", "CHART")?;
|
|
682
|
+
self.double(chart, "base_parameter")?;
|
|
683
|
+
self.double(chart, "base_scale")?;
|
|
684
|
+
self.optional_double(chart, "chordal_error")?;
|
|
685
|
+
self.optional_double(chart, "angular_error")?;
|
|
686
|
+
let count = self.nonnegative_integer(chart, "chart_count")?;
|
|
687
|
+
self.intersection_points(chart, usize::try_from(count).unwrap_or(usize::MAX))?;
|
|
688
|
+
for field in ["start", "end"] {
|
|
689
|
+
let limit = self.required_typed_node(node, field, "LIMIT")?;
|
|
690
|
+
let count = match self.character(limit, "type")? {
|
|
691
|
+
b'H' | b'L' => 1,
|
|
692
|
+
b'T' => 2,
|
|
693
|
+
_ => {
|
|
694
|
+
return Err(self.invalid_geometry(
|
|
695
|
+
limit,
|
|
696
|
+
"type",
|
|
697
|
+
"invalid intersection limit kind",
|
|
698
|
+
));
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
self.intersection_points(limit, count)?;
|
|
702
|
+
}
|
|
663
703
|
let surface_indices = self.pointer_array(node, "surface")?;
|
|
664
704
|
if surface_indices.len() != 2 {
|
|
665
705
|
return Err(self.invalid_field(
|
|
@@ -684,12 +724,71 @@ impl<'a> Mapper<'a> {
|
|
|
684
724
|
&self.ids.surfaces,
|
|
685
725
|
)?,
|
|
686
726
|
];
|
|
727
|
+
let intersection_data = self.optional_source_if_field(node, "intersection_data")?;
|
|
728
|
+
if intersection_data.is_some() {
|
|
729
|
+
self.required_typed_node(node, "intersection_data", "INTERSECTION_DATA")?;
|
|
730
|
+
}
|
|
687
731
|
Ok(CurveKind::Intersection {
|
|
688
732
|
surfaces,
|
|
689
733
|
chart: self.required_source(node, "chart")?,
|
|
690
734
|
start: self.required_source(node, "start")?,
|
|
691
735
|
end: self.required_source(node, "end")?,
|
|
692
|
-
intersection_data
|
|
736
|
+
intersection_data,
|
|
737
|
+
})
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
fn intersection_points(&self, node: &RawNode, count: usize) -> Result<(), ParseError> {
|
|
741
|
+
let values = &self.field(node, "hvec")?.values;
|
|
742
|
+
if count == 0 || values.len() != count {
|
|
743
|
+
return Err(self.invalid_geometry(node, "hvec", "intersection point count mismatch"));
|
|
744
|
+
}
|
|
745
|
+
for value in values {
|
|
746
|
+
match value {
|
|
747
|
+
FieldValue::IntersectionPoint([Some(x), Some(y), Some(z)])
|
|
748
|
+
if x.is_finite() && y.is_finite() && z.is_finite() => {}
|
|
749
|
+
_ => {
|
|
750
|
+
return Err(self.invalid_geometry(
|
|
751
|
+
node,
|
|
752
|
+
"hvec",
|
|
753
|
+
"intersection point is null or non-finite",
|
|
754
|
+
));
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
Ok(())
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
fn surface_parametric_curve(&self, node: &RawNode) -> Result<CurveKind, ParseError> {
|
|
762
|
+
let parameter_curve = self.required_typed_node(node, "b_curve", "B_CURVE")?;
|
|
763
|
+
let nurbs = self.required_typed_node(parameter_curve, "nurbs", "NURBS_CURVE")?;
|
|
764
|
+
let rational = self.logical(nurbs, "rational")?;
|
|
765
|
+
let dimension = self.positive_short(nurbs, "vertex_dim")?;
|
|
766
|
+
if dimension != if rational { 3 } else { 2 } {
|
|
767
|
+
return Err(self.invalid_geometry(
|
|
768
|
+
nurbs,
|
|
769
|
+
"vertex_dim",
|
|
770
|
+
"surface parameter curve must have two coordinates plus an optional weight",
|
|
771
|
+
));
|
|
772
|
+
}
|
|
773
|
+
let tolerance_to_original = self.optional_double(node, "tolerance_to_original")?;
|
|
774
|
+
if tolerance_to_original.is_some_and(|value| value < 0.0) {
|
|
775
|
+
return Err(self.invalid_geometry(node, "tolerance_to_original", "negative tolerance"));
|
|
776
|
+
}
|
|
777
|
+
Ok(CurveKind::SurfaceParametric {
|
|
778
|
+
surface: self.required_id(node, "surface", "surface geometry", &self.ids.surfaces)?,
|
|
779
|
+
parameter_curve: self.required_id(
|
|
780
|
+
node,
|
|
781
|
+
"b_curve",
|
|
782
|
+
"curve geometry",
|
|
783
|
+
&self.ids.curves,
|
|
784
|
+
)?,
|
|
785
|
+
original_curve: self.optional_id(
|
|
786
|
+
node,
|
|
787
|
+
"original",
|
|
788
|
+
"curve geometry",
|
|
789
|
+
&self.ids.curves,
|
|
790
|
+
)?,
|
|
791
|
+
tolerance_to_original,
|
|
693
792
|
})
|
|
694
793
|
}
|
|
695
794
|
|
|
@@ -720,28 +819,42 @@ impl<'a> Mapper<'a> {
|
|
|
720
819
|
flat_vertices.len(),
|
|
721
820
|
)?;
|
|
722
821
|
let degree = self.positive_short(nurbs, "degree")?;
|
|
723
|
-
let
|
|
724
|
-
let
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
.
|
|
728
|
-
|
|
822
|
+
let rational = self.logical(nurbs, "rational")?;
|
|
823
|
+
let periodic = self.logical(nurbs, "periodic")?;
|
|
824
|
+
let closed = self.logical(nurbs, "closed")?;
|
|
825
|
+
if control_count <= u32::from(degree)
|
|
826
|
+
|| !(if rational { 3..=4 } else { 2..=3 }).contains(&vertex_dimension)
|
|
827
|
+
|| (periodic && !closed)
|
|
828
|
+
{
|
|
729
829
|
return Err(self.invalid_geometry(
|
|
730
830
|
nurbs,
|
|
731
|
-
"
|
|
732
|
-
|
|
733
|
-
"expanded knot count {actual_expanded} does not equal vertices + degree + 1 ({expected_expanded})"
|
|
734
|
-
),
|
|
831
|
+
"n_vertices",
|
|
832
|
+
"invalid NURBS dimensions or closure",
|
|
735
833
|
));
|
|
736
834
|
}
|
|
835
|
+
if rational
|
|
836
|
+
&& flat_vertices
|
|
837
|
+
.chunks(usize::from(vertex_dimension))
|
|
838
|
+
.any(|vertex| vertex.last().is_none_or(|weight| *weight <= 0.0))
|
|
839
|
+
{
|
|
840
|
+
return Err(self.invalid_geometry(nurbs, "vertices", "NURBS weights must be positive"));
|
|
841
|
+
}
|
|
842
|
+
self.validate_nurbs_knots(
|
|
843
|
+
nurbs,
|
|
844
|
+
"knots",
|
|
845
|
+
&knots,
|
|
846
|
+
&multiplicities,
|
|
847
|
+
control_count,
|
|
848
|
+
degree,
|
|
849
|
+
)?;
|
|
737
850
|
Ok(NurbsCurve {
|
|
738
851
|
degree,
|
|
739
852
|
control_vertex_count: control_count,
|
|
740
853
|
vertex_dimension,
|
|
741
854
|
knot_type: self.byte(nurbs, "knot_type")?,
|
|
742
|
-
periodic
|
|
743
|
-
closed
|
|
744
|
-
rational
|
|
855
|
+
periodic,
|
|
856
|
+
closed,
|
|
857
|
+
rational,
|
|
745
858
|
curve_form: self.byte(nurbs, "curve_form")?,
|
|
746
859
|
control_vertices: flat_vertices
|
|
747
860
|
.chunks(usize::from(vertex_dimension))
|
|
@@ -792,8 +905,46 @@ impl<'a> Mapper<'a> {
|
|
|
792
905
|
)?;
|
|
793
906
|
let u_degree = self.positive_short(nurbs, "u_degree")?;
|
|
794
907
|
let v_degree = self.positive_short(nurbs, "v_degree")?;
|
|
795
|
-
self.
|
|
796
|
-
|
|
908
|
+
self.validate_nurbs_knots(
|
|
909
|
+
nurbs,
|
|
910
|
+
"u_knots",
|
|
911
|
+
&u_knots,
|
|
912
|
+
&u_multiplicities,
|
|
913
|
+
u_count,
|
|
914
|
+
u_degree,
|
|
915
|
+
)?;
|
|
916
|
+
self.validate_nurbs_knots(
|
|
917
|
+
nurbs,
|
|
918
|
+
"v_knots",
|
|
919
|
+
&v_knots,
|
|
920
|
+
&v_multiplicities,
|
|
921
|
+
v_count,
|
|
922
|
+
v_degree,
|
|
923
|
+
)?;
|
|
924
|
+
let rational = self.logical(nurbs, "rational")?;
|
|
925
|
+
let u_periodic = self.logical(nurbs, "u_periodic")?;
|
|
926
|
+
let v_periodic = self.logical(nurbs, "v_periodic")?;
|
|
927
|
+
let u_closed = self.logical(nurbs, "u_closed")?;
|
|
928
|
+
let v_closed = self.logical(nurbs, "v_closed")?;
|
|
929
|
+
if u_count <= u32::from(u_degree)
|
|
930
|
+
|| v_count <= u32::from(v_degree)
|
|
931
|
+
|| vertex_dimension != if rational { 4 } else { 3 }
|
|
932
|
+
|| (u_periodic && !u_closed)
|
|
933
|
+
|| (v_periodic && !v_closed)
|
|
934
|
+
{
|
|
935
|
+
return Err(self.invalid_geometry(
|
|
936
|
+
nurbs,
|
|
937
|
+
"vertices",
|
|
938
|
+
"invalid NURBS surface dimensions or closure",
|
|
939
|
+
));
|
|
940
|
+
}
|
|
941
|
+
if rational
|
|
942
|
+
&& flat_vertices
|
|
943
|
+
.chunks(usize::from(vertex_dimension))
|
|
944
|
+
.any(|vertex| vertex.last().is_none_or(|weight| *weight <= 0.0))
|
|
945
|
+
{
|
|
946
|
+
return Err(self.invalid_geometry(nurbs, "vertices", "NURBS weights must be positive"));
|
|
947
|
+
}
|
|
797
948
|
Ok(NurbsSurface {
|
|
798
949
|
u_degree,
|
|
799
950
|
v_degree,
|
|
@@ -802,11 +953,11 @@ impl<'a> Mapper<'a> {
|
|
|
802
953
|
vertex_dimension,
|
|
803
954
|
u_knot_type: self.byte(nurbs, "u_knot_type")?,
|
|
804
955
|
v_knot_type: self.byte(nurbs, "v_knot_type")?,
|
|
805
|
-
u_periodic
|
|
806
|
-
v_periodic
|
|
807
|
-
u_closed
|
|
808
|
-
v_closed
|
|
809
|
-
rational
|
|
956
|
+
u_periodic,
|
|
957
|
+
v_periodic,
|
|
958
|
+
u_closed,
|
|
959
|
+
v_closed,
|
|
960
|
+
rational,
|
|
810
961
|
surface_form: self.byte(nurbs, "surface_form")?,
|
|
811
962
|
control_vertices: flat_vertices
|
|
812
963
|
.chunks(usize::from(vertex_dimension))
|
|
@@ -827,24 +978,60 @@ impl<'a> Mapper<'a> {
|
|
|
827
978
|
})
|
|
828
979
|
}
|
|
829
980
|
|
|
830
|
-
|
|
981
|
+
#[allow(clippy::too_many_arguments)]
|
|
982
|
+
fn validate_nurbs_knots(
|
|
831
983
|
&self,
|
|
832
984
|
node: &RawNode,
|
|
833
985
|
field: &'static str,
|
|
986
|
+
knots: &[f64],
|
|
834
987
|
multiplicities: &[u16],
|
|
835
|
-
|
|
988
|
+
control_count: u32,
|
|
836
989
|
degree: u16,
|
|
837
990
|
) -> Result<(), ParseError> {
|
|
838
|
-
|
|
839
|
-
|
|
991
|
+
if knots.len() < 2
|
|
992
|
+
|| knots.windows(2).any(|pair| pair[0] >= pair[1])
|
|
993
|
+
|| multiplicities.iter().any(|&count| count > degree + 1)
|
|
994
|
+
|| multiplicities[1..multiplicities.len() - 1]
|
|
995
|
+
.iter()
|
|
996
|
+
.any(|&count| count > degree)
|
|
997
|
+
{
|
|
998
|
+
return Err(self.invalid_geometry(
|
|
999
|
+
node,
|
|
1000
|
+
field,
|
|
1001
|
+
"invalid distinct knots or multiplicities",
|
|
1002
|
+
));
|
|
1003
|
+
}
|
|
1004
|
+
let expected_expanded = u64::from(control_count) + u64::from(degree) + 1;
|
|
1005
|
+
let actual_expanded = multiplicities
|
|
840
1006
|
.iter()
|
|
841
1007
|
.map(|value| u64::from(*value))
|
|
842
1008
|
.sum::<u64>();
|
|
843
|
-
if
|
|
1009
|
+
if actual_expanded != expected_expanded {
|
|
1010
|
+
return Err(self.invalid_geometry(
|
|
1011
|
+
node,
|
|
1012
|
+
field,
|
|
1013
|
+
format!(
|
|
1014
|
+
"expanded knot count {actual_expanded} does not equal vertices + degree + 1 ({expected_expanded})"
|
|
1015
|
+
),
|
|
1016
|
+
));
|
|
1017
|
+
}
|
|
1018
|
+
// Only [t_degree, t_control_count] is fully defined. Find these knots
|
|
1019
|
+
// without allocating the expanded vector, including imaginary knots.
|
|
1020
|
+
let knot_at = |index: u64| {
|
|
1021
|
+
let mut end = 0_u64;
|
|
1022
|
+
knots
|
|
1023
|
+
.iter()
|
|
1024
|
+
.zip(multiplicities)
|
|
1025
|
+
.find_map(|(&knot, &count)| {
|
|
1026
|
+
end += u64::from(count);
|
|
1027
|
+
(index < end).then_some(knot)
|
|
1028
|
+
})
|
|
1029
|
+
};
|
|
1030
|
+
if knot_at(u64::from(degree)) >= knot_at(u64::from(control_count)) {
|
|
844
1031
|
return Err(self.invalid_geometry(
|
|
845
1032
|
node,
|
|
846
1033
|
field,
|
|
847
|
-
|
|
1034
|
+
"NURBS active parameter range must have positive length",
|
|
848
1035
|
));
|
|
849
1036
|
}
|
|
850
1037
|
Ok(())
|