python-cad-tools 0.1.18__tar.gz → 0.1.19__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.
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.github/workflows/ci.yml +19 -28
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/CHANGELOG.md +18 -0
- {python_cad_tools-0.1.18/src/python_cad_tools.egg-info → python_cad_tools-0.1.19}/PKG-INFO +1 -1
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/toolchain.md +3 -1
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/artifacts.py +7 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/build.py +7 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/context.py +2 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/__init__.py +22 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/elements.py +12 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/geometry.py +9 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/units.py +13 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/validation.py +1 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19/src/python_cad_tools.egg-info}/PKG-INFO +1 -1
- python_cad_tools-0.1.19/src/python_cad_tools.egg-info/scm_version.json +8 -0
- python_cad_tools-0.1.18/src/python_cad_tools.egg-info/scm_version.json +0 -8
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.gitattributes +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.githooks/pre-push +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.github/workflows/downstream-compatibility.yml +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.github/workflows/release-candidate.yml +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.github/workflows/release.yml +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.gitignore +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.opencode/commands/autocommit.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.opencode/tools/specrepo-autocommit.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.opencode/tools/specrepo-autocommit.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/AGENTS.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/CLAUDE.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/LICENSE +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/MANIFEST.in +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/README.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/build-semantics.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/drawing-extensions.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/manifests.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/neutral-model.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/project-configuration.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/public-api.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/spikes/curved-geometry-ifc-bounds.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/spikes/format-feasibility.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/two-tier-contract.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/docs/viewer-delivery.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/pyproject.toml +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/setup.cfg +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/__init__.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/__main__.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_locking.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_project_loader.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_project_state.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_scaffold.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_transaction.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/app.webmanifest +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/asset-manifest.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/animationGroup-CMgMiFPo.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bakedVertexAnimation-BlpwZEna.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/basisTextureLoader-pxgVvwE7.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/brdfTextureTools-CL1Nnrm1.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpFragment-BNBjNOnF.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpVertex-BTawYPw8.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpVertexDeclaration-B_fffQFY.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/clipPlaneFragment-D1ZAafqO.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/clipPlaneVertex-BC_wnvpq.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/cubemapToSphericalPolynomial-DeA9LJ87.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/dds-C5zm4fz8.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/dds.pure-B_7lJeYI.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/ddsTextureLoader-DsS5rL5j.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/default.fragment-BUHDudIn.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/default.vertex-B80Wq2Ab.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/defaultUboDeclaration-DuGcl3VN.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/dumpTools-1F1Rx0a0.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/envTextureLoader-DqI1ceC5.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/exrTextureLoader-DmNwF2B5.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyForceBlock-DmvfeucL.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyImpulseBlock-ChgIpPqh.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphArrayIndexBlock-_JwXSrlj.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBezierCurveEasingBlock-B-T0qVRw.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBinaryOperationBlock-TpZm5BfV.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBranchBlock-CNwAs8cP.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCachedOperationBlock-DaEYpjja.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCancelDelayBlock-Dc4RKYSf.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCodeExecutionBlock-DCxeE8wr.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConditionalDataBlock-TckZ2SGl.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConsoleLogBlock-B5e69wX5.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConstantBlock-3ktOI1lC.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphContextBlock-XTBtETD_.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCounterBlock-Pb64y9OD.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDataSwitchBlock-DsG4QDCF.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDebounceBlock-B_XjPDoZ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDebugBlock-CD6lTvpS.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDoNBlock-0NvER8W0.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphEasingBlock-B6hapywt.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphFlipFlopBlock-D1uyBOpq.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphForLoopBlock-BYD81Gof.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphFunctionReferenceBlock-zABkEq-X.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGLTFDataProvider-B0ofoVrD.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAngularVelocityBlock-DPTUNnTb.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAssetBlock-B8_99mSz.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetLinearVelocityBlock-DFYXgPrA.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPhysicsMassPropertiesBlock-DA6AqPR7.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPropertyBlock-Bp4o9QmW.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetSoundVolumeBlock-BAmdegmU.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetVariableBlock-Cd8Y6leR.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIndexOfBlock-CGYxKZZY.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphInterpolationBlock-CwjeWPr7.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIsKeyPressedBlock-rNAEqrST.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIsSoundPlayingBlock-BTztAQ_0.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphJsonPointerParserBlock-DoLWKXUb.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyDownEventBlock-DPIi37WK.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyUpEventBlock-ZV1Tim4d.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyboardEventBlock-ClUSFYDa.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMathBlocks-BEiYY5fC.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMathCombineExtractBlocks-CVfFjT4m.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMatrixMathBlocks-B6l0dCDc.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMeshPickEventBlock-kdpuo1mU.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMultiGateBlock-n99NMOON.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseAnimationBlock-DXKPP4nK.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseSoundBlock-e2k4W8Bc.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPhysicsCollisionEventBlock-ClgKwXfJ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPlayAnimationBlock-BZj6MNgX.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPlaySoundBlock-BnzlrpjK.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerDownEventBlock-CQiX1RZi.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerMoveEventBlock-B_JzBfd9.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOutEventBlock-B-xKCRP6.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOverEventBlock-DPC5GKft.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerUpEventBlock-hCR14WZY.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphReceiveCustomEventBlock-EOc5SmbK.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneReadyEventBlock-BAOJ-S5R.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneTickEventBlock-BJla1nDw.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSendCustomEventBlock-CbJzCBSw.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSequenceBlock-C0E5Vhwk.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetAngularVelocityBlock-Crx1sltA.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetDelayBlock-t-D4JM8I.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetLinearVelocityBlock-DKNa-lhN.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPhysicsMotionTypeBlock-BIeMWJwi.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPropertyBlock-CFERwfo5.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetSoundVolumeBlock-B8fGBso9.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetVariableBlock-D3NUXLsU.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSoundEndedEventBlock-BsojQIIQ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphStopAnimationBlock-Bhvi4mzM.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphStopSoundBlock-BL-vDlPP.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSwitchBlock-q5uox2Ll.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphThrottleBlock-ZvIobaF-.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphTransformCoordinatesSystemBlock-DC7IZTrj.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphTypeToTypeBlocks-DsmLuQmd.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphUnaryOperationBlock-CeFOvM8N.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphVectorMathBlocks-O_o0PB3R.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphWaitAllBlock-CS8S_sto.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphWhileLoopBlock-BogzY-TI.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/fogFragment-5iY5mDF9.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-CzELCfrg.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-Dm4qQcCl.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-Dl5Knagi.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-gV6NfBr2.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BU7N8GWm.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BYh0LKwp.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DGCqlu5B.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DPRpU6I6.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.vertex-D6831_Db.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.vertex-DVVqYQkj.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.fragment-CJ5P29rW.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.fragment-eMPAGW-C.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.vertex-Cfmd-eH1.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.vertex-D8aj2PHd.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowBlurPostProcess.fragment-BNUj6Ok4.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.fragment-BMfCbDSO.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.vertex-HFoIGtvW.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.fragment-DcbXX8O5.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.vertex-C6kfp5Df.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/harmonicsFunctions-B_Rux4W4.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/hdrTextureLoader-BGQvgh0h.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/helperFunctions-DfEEUVrK.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/iesTextureLoader-DRIv8q-c.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/index-Bi_hQlRi.css +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/index-QUv88KPb.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlur.fragment-AIxPvzg7.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlur.fragment-B-fzpNXl.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlur.vertex-BeCpz_iB.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlur.vertex-LF_ZsFNn.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-0MaBFn29.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-CKf1P4fb.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/ktxTextureLoader-tKPsUacI.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/lightFragment-k2nRX45x.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/logDepthDeclaration-BGXXcOUJ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/logDepthVertex-BC72KyzN.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/mainUVVaryingDeclaration-BCMZuxRE.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/mesh.vertexData.functions-ayNlGC5K.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/meshUboDeclaration-Cxk75_zo.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/oitFragment-BtwWIihL.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-8rnUKL54.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-C6yWZfQI.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.vertex-DGh-kC4B.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.vertex-DbnVIs8Y.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrMaterial.pure-CFHhabYh.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrMaterialLoadingAdapter-BQGAj-f6.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-BMK7l2Ba.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-DNsGu5u0.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-Cd1JAAAL.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-rBzbf9n3.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/packingFunctions-Dji1Rr-b.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/packingFunctions-_goA4OEm.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pass.fragment-CgGToehX.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-CqqQ20XF.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-D93dlgjG.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbr.fragment-YSvcDJjz.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbr.vertex-BOhSAeHX.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrBRDFFunctions-DTEwurLZ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrDebug-B4IzJZHZ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrIBLFunctions-gJ0KErMb.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrMaterial.pure-BRIxFz02.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrMaterialLoadingAdapter--NRrZRBU.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrUboDeclaration-6dxbcrtA.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/postprocess.vertex-ZxthID8t.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/procedural.vertex-BSVnGss-.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/procedural.vertex-DzIg_d-k.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/reflectionFunction-CgKY-0t6.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdDecode.fragment-CAfeJDpQ.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-D7xEO0B-.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-DIzz0LC4.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/sceneUboDeclaration-kGrRDglr.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-CgQTw0M7.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-DnEEx4Gs.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/tgaTextureLoader-CwaQqeYn.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/vertexColorMixing-C2cK_vck.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/favicon.svg +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/index.html +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/sw.js +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/build-info.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/cli.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/determinism.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/_catalog.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/_validation.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exceptions.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/__init__.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/base.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/__init__.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/annotations.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/dxf.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/model.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/pdf.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/primitives.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/projection.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/svg.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/glb.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/ifc.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/quantities.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/step.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/manifests.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/project_config.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/py.typed +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/recipes.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/runtime_sync.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/build-manifest-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/design-manifest-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/download-manifest-2.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/drawing-annotations-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/glb-manifest-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/ifc-validation-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/quantities-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/run-metadata-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/site-metadata-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/step-validation-1.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/site.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/.gitignore +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/README.md +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/config.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/drawing_annotations.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/generated/.gitkeep +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/model.py +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/pyproject.toml +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/SOURCES.txt +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/dependency_links.txt +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/entry_points.txt +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/requires.txt +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/scm_file_list.json +0 -0
- {python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/top_level.txt +0 -0
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
# creates the tag and triggers this run. Keeping publish logic in one
|
|
18
18
|
# gated place (instead of duplicating it in release.yml) avoids two
|
|
19
19
|
# workflows racing to publish the same version.
|
|
20
|
+
#
|
|
21
|
+
# Test tiers (workspace test-cost-reduction, 2026-10-12): pushes and pull
|
|
22
|
+
# requests run the checks a code change can break on Linux, plus one macOS
|
|
23
|
+
# platform job. Version tags and manual dispatch (the release path, before
|
|
24
|
+
# PyPI) also run Windows, the per-extra toolchain matrix on macOS and Linux,
|
|
25
|
+
# and the platform locks. macOS minutes bill 10x on this private repository.
|
|
20
26
|
name: CI
|
|
21
27
|
|
|
22
28
|
on:
|
|
@@ -227,15 +233,15 @@ jobs:
|
|
|
227
233
|
done
|
|
228
234
|
echo "All tree shape checks passed."
|
|
229
235
|
|
|
230
|
-
# Confirms init/build works on Linux, macOS, and Windows
|
|
231
|
-
# skips ruff/mypy since static checks
|
|
232
|
-
# cross-platform contract, just the CLI behavior.
|
|
236
|
+
# Confirms init/build works on Linux, macOS, and Windows (Windows only
|
|
237
|
+
# on the release tier). Windows skips ruff/mypy since static checks
|
|
238
|
+
# aren't part of the cross-platform contract, just the CLI behavior.
|
|
233
239
|
supported-platforms:
|
|
234
240
|
name: Supported platforms (${{ matrix.os }})
|
|
235
241
|
strategy:
|
|
236
242
|
fail-fast: false
|
|
237
243
|
matrix:
|
|
238
|
-
os: [ubuntu-latest,
|
|
244
|
+
os: ${{ fromJSON((startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') && '["ubuntu-latest","macos-latest","windows-latest"]' || '["ubuntu-latest","macos-latest"]') }}
|
|
239
245
|
runs-on: ${{ matrix.os }}
|
|
240
246
|
steps:
|
|
241
247
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
@@ -263,9 +269,10 @@ jobs:
|
|
|
263
269
|
|
|
264
270
|
# Generates a per-OS `pip freeze` lockfile as a downloadable
|
|
265
271
|
# artifact for reference. Informational only — not enforced or
|
|
266
|
-
# committed anywhere automatically.
|
|
272
|
+
# committed anywhere automatically. Release tier only.
|
|
267
273
|
platform-locks:
|
|
268
274
|
name: Platform lock generation (${{ matrix.os }})
|
|
275
|
+
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
|
|
269
276
|
strategy:
|
|
270
277
|
fail-fast: false
|
|
271
278
|
matrix:
|
|
@@ -297,40 +304,27 @@ jobs:
|
|
|
297
304
|
path: ${{ matrix.lock }}
|
|
298
305
|
|
|
299
306
|
# Confirms every optional dependency group (cad, bim, mesh, ...)
|
|
300
|
-
# installs cleanly and imports across OS/Python combinations.
|
|
301
|
-
#
|
|
302
|
-
#
|
|
307
|
+
# installs cleanly and imports across OS/Python combinations. Pushes
|
|
308
|
+
# and PRs run core and all on Linux for both Pythons; the release tier
|
|
309
|
+
# runs every group on Linux and macOS. The matrix itself is narrowed,
|
|
310
|
+
# so no runner starts for a cell that would be skipped.
|
|
303
311
|
toolchain-matrix:
|
|
304
312
|
name: Toolchain matrix (${{ matrix.os }}, py${{ matrix.python }}, ${{ matrix.group }})
|
|
305
313
|
strategy:
|
|
306
314
|
fail-fast: false
|
|
307
315
|
matrix:
|
|
308
|
-
os: [ubuntu-latest,
|
|
316
|
+
os: ${{ fromJSON((startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') && '["ubuntu-latest","macos-latest"]' || '["ubuntu-latest"]') }}
|
|
309
317
|
python: ["3.12", "3.13"]
|
|
310
|
-
group: [core,
|
|
318
|
+
group: ${{ fromJSON((startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') && '["core","cad","bim","mesh","drawings","engineering","visualization","all"]' || '["core","all"]') }}
|
|
311
319
|
runs-on: ${{ matrix.os }}
|
|
312
320
|
steps:
|
|
313
321
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
314
|
-
# Full matrix on main/tags/release-candidates; a fast core+all subset on pull requests.
|
|
315
|
-
- name: Determine whether this matrix cell runs
|
|
316
|
-
id: gate
|
|
317
|
-
run: |
|
|
318
|
-
if [ "${{ github.event_name }}" = "pull_request" ] && \
|
|
319
|
-
! { [ "${{ matrix.os }}" = "ubuntu-latest" ] && [ "${{ matrix.python }}" = "3.13" ] && \
|
|
320
|
-
{ [ "${{ matrix.group }}" = "core" ] || [ "${{ matrix.group }}" = "all" ]; }; }; then
|
|
321
|
-
echo "run=false" >> "$GITHUB_OUTPUT"
|
|
322
|
-
else
|
|
323
|
-
echo "run=true" >> "$GITHUB_OUTPUT"
|
|
324
|
-
fi
|
|
325
322
|
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
326
|
-
if: steps.gate.outputs.run == 'true'
|
|
327
323
|
with:
|
|
328
324
|
python-version: ${{ matrix.python }}
|
|
329
325
|
cache: pip
|
|
330
326
|
- run: python -m pip install --upgrade pip
|
|
331
|
-
if: steps.gate.outputs.run == 'true'
|
|
332
327
|
- name: Install capability group
|
|
333
|
-
if: steps.gate.outputs.run == 'true'
|
|
334
328
|
run: |
|
|
335
329
|
if [ "${{ matrix.group }}" = "core" ]; then
|
|
336
330
|
pip install -e .
|
|
@@ -338,9 +332,7 @@ jobs:
|
|
|
338
332
|
pip install -e ".[${{ matrix.group }}]"
|
|
339
333
|
fi
|
|
340
334
|
- run: pip check
|
|
341
|
-
if: steps.gate.outputs.run == 'true'
|
|
342
335
|
- name: Import declared libraries for this group
|
|
343
|
-
if: steps.gate.outputs.run == 'true'
|
|
344
336
|
run: |
|
|
345
337
|
python - <<'PY'
|
|
346
338
|
import importlib
|
|
@@ -384,7 +376,7 @@ jobs:
|
|
|
384
376
|
print(json.dumps(report, indent=2, sort_keys=True))
|
|
385
377
|
PY
|
|
386
378
|
- name: Tier-2 interop smoke and no-GUI assertion
|
|
387
|
-
if:
|
|
379
|
+
if: matrix.group == 'all'
|
|
388
380
|
run: |
|
|
389
381
|
python - <<'PY'
|
|
390
382
|
import sys
|
|
@@ -413,7 +405,6 @@ jobs:
|
|
|
413
405
|
print("Tier-2 interop smoke and no-GUI assertion passed.")
|
|
414
406
|
PY
|
|
415
407
|
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
|
|
416
|
-
if: steps.gate.outputs.run == 'true'
|
|
417
408
|
with:
|
|
418
409
|
name: toolchain-compatibility-${{ matrix.os }}-py${{ matrix.python }}-${{ matrix.group }}
|
|
419
410
|
path: toolchain-compatibility.json
|
|
@@ -7,6 +7,24 @@ stable release is published.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.19] - 2026-10-19
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Every public function and class in the authoring modules (`artifacts`,
|
|
15
|
+
`build`, `context`, `drawings`, `elements`, `geometry`, `units`,
|
|
16
|
+
`validation`) has a one-line docstring stating its units and, for
|
|
17
|
+
geometry, its placement:
|
|
18
|
+
- `box` puts its minimum corner at the origin;
|
|
19
|
+
- `prism_between` starts at a bottom corner, with its width to the left
|
|
20
|
+
of the run;
|
|
21
|
+
- `Placement` is recorded only and never moves geometry.
|
|
22
|
+
|
|
23
|
+
Tools that list the public API with signatures and first docstring
|
|
24
|
+
lines now describe each helper. Behavior is unchanged.
|
|
25
|
+
- Routine CI runs a smaller platform and extras matrix. Version tags and
|
|
26
|
+
manual dispatch still run the full release matrix.
|
|
27
|
+
|
|
10
28
|
## [0.1.18] - 2026-10-08
|
|
11
29
|
|
|
12
30
|
### Fixed
|
|
@@ -90,7 +90,9 @@ See `docs/two-tier-contract.md` for what "Tier 1" and "Tier 2" mean.
|
|
|
90
90
|
## Compatibility verification
|
|
91
91
|
|
|
92
92
|
The `toolchain-matrix` CI job (`.github/workflows/ci.yml`) installs every
|
|
93
|
-
capability group across `{ubuntu-latest, macos-latest} × {3.12, 3.13}
|
|
93
|
+
capability group across `{ubuntu-latest, macos-latest} × {3.12, 3.13}` on
|
|
94
|
+
version tags and manual runs (the release path; pushes and pull requests
|
|
95
|
+
run `core` and `all` on Linux for both Pythons), runs
|
|
94
96
|
`pip check`, imports every library the group declares, and — for `all` — runs
|
|
95
97
|
a Tier-2 interop smoke (a shape crosses build123d → `geometry.tessellate` →
|
|
96
98
|
trimesh → ifcopenshell read-back → ezdxf) plus the no-GUI assertion. It
|
|
@@ -25,6 +25,7 @@ _EXPECTED_REPRESENTATION_TYPE = {None: "Tessellation", "extruded_profile": "Swep
|
|
|
25
25
|
|
|
26
26
|
@dataclass(frozen=True, slots=True)
|
|
27
27
|
class ArtifactRecord:
|
|
28
|
+
"""One generated file: its path, size, SHA-256, media type and producer."""
|
|
28
29
|
path: str
|
|
29
30
|
size: int
|
|
30
31
|
sha256: str
|
|
@@ -37,6 +38,7 @@ class ArtifactRecord:
|
|
|
37
38
|
|
|
38
39
|
@dataclass(frozen=True, slots=True)
|
|
39
40
|
class VerificationResult:
|
|
41
|
+
"""The outcome of ``verify_build_output``: whether the output matches its manifest, and any issues."""
|
|
40
42
|
ok: bool
|
|
41
43
|
output_root: Path
|
|
42
44
|
issues: tuple[ValidationIssue, ...]
|
|
@@ -48,6 +50,7 @@ class VerificationResult:
|
|
|
48
50
|
|
|
49
51
|
@dataclass(frozen=True, slots=True)
|
|
50
52
|
class PackageBuildInfo:
|
|
53
|
+
"""The installed python-cad-tools distribution's version and build provenance."""
|
|
51
54
|
schema_id: Literal["urn:python-cad-tools:schema:package-build-info:1"]
|
|
52
55
|
schema_version: Literal[1]
|
|
53
56
|
distribution: Literal["python-cad-tools"]
|
|
@@ -58,6 +61,7 @@ class PackageBuildInfo:
|
|
|
58
61
|
|
|
59
62
|
|
|
60
63
|
def load_build_manifest(path: Path) -> dict[str, Any]:
|
|
64
|
+
"""Read and schema-check a build manifest JSON file."""
|
|
61
65
|
value = validate_json_document(path)
|
|
62
66
|
if value["schema_id"] != "urn:python-cad-tools:schema:build-manifest:1":
|
|
63
67
|
raise ArtifactIntegrityError(f"Not a build manifest: {path}")
|
|
@@ -65,6 +69,7 @@ def load_build_manifest(path: Path) -> dict[str, Any]:
|
|
|
65
69
|
|
|
66
70
|
|
|
67
71
|
def load_design_manifest(path: Path) -> dict[str, Any]:
|
|
72
|
+
"""Read and schema-check a design manifest JSON file."""
|
|
68
73
|
value = validate_json_document(path)
|
|
69
74
|
if value["schema_id"] != "urn:python-cad-tools:schema:design-manifest:1":
|
|
70
75
|
raise ArtifactIntegrityError(f"Not a design manifest: {path}")
|
|
@@ -171,6 +176,7 @@ def verify_output_root(output_root: Path, project_root: Path | None = None) -> V
|
|
|
171
176
|
|
|
172
177
|
|
|
173
178
|
def verify_build_output(project_root: Path) -> VerificationResult:
|
|
179
|
+
"""Check that a project's generated output still matches its build manifest."""
|
|
174
180
|
from ._locking import project_lock
|
|
175
181
|
from ._transaction import recover_promotion
|
|
176
182
|
from .project_config import load_project_config, output_path, resolve_project_root
|
|
@@ -184,6 +190,7 @@ def verify_build_output(project_root: Path) -> VerificationResult:
|
|
|
184
190
|
|
|
185
191
|
|
|
186
192
|
def get_package_build_info() -> PackageBuildInfo:
|
|
193
|
+
"""Return the installed distribution's build information."""
|
|
187
194
|
try:
|
|
188
195
|
document = json.loads(resources.files("python_cad_tools").joinpath("build-info.json").read_text(encoding="utf-8"))
|
|
189
196
|
except (FileNotFoundError, json.JSONDecodeError) as error:
|
|
@@ -32,18 +32,21 @@ type FormatName = Literal["step", "ifc", "glb", "drawings", "quantities"]
|
|
|
32
32
|
|
|
33
33
|
@dataclass(frozen=True, slots=True)
|
|
34
34
|
class BuildOptions:
|
|
35
|
+
"""Options for ``build_project``: the project root and the formats to build (default: the project's own)."""
|
|
35
36
|
project_root: Path
|
|
36
37
|
formats: tuple[FormatName, ...] | None = None
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
@dataclass(frozen=True, slots=True)
|
|
40
41
|
class ValidationOptions:
|
|
42
|
+
"""Options for ``validate_project``: the project root and the formats to check (default: the project's own)."""
|
|
41
43
|
project_root: Path
|
|
42
44
|
formats: tuple[FormatName, ...] | None = None
|
|
43
45
|
|
|
44
46
|
|
|
45
47
|
@dataclass(frozen=True, slots=True)
|
|
46
48
|
class BuildResult:
|
|
49
|
+
"""What ``build_project`` produced: its output folder, artifacts, build manifest and hashes."""
|
|
47
50
|
project_root: Path
|
|
48
51
|
output_root: Path
|
|
49
52
|
formats: tuple[FormatName, ...]
|
|
@@ -57,6 +60,7 @@ class BuildResult:
|
|
|
57
60
|
|
|
58
61
|
@dataclass(frozen=True, slots=True)
|
|
59
62
|
class ValidationReport:
|
|
63
|
+
"""The issues ``validate_project`` found; ``ok`` is true when none is fatal."""
|
|
60
64
|
project_root: Path
|
|
61
65
|
formats: tuple[FormatName, ...]
|
|
62
66
|
issues: tuple[ValidationIssue, ...]
|
|
@@ -79,6 +83,7 @@ EXPORTERS: dict[str, type[Any]] = {
|
|
|
79
83
|
|
|
80
84
|
|
|
81
85
|
def build_project(options: BuildOptions) -> BuildResult:
|
|
86
|
+
"""Build the project's requested formats into its output folder and return the result."""
|
|
82
87
|
if not isinstance(options, BuildOptions):
|
|
83
88
|
raise TypeError("build_project expects BuildOptions")
|
|
84
89
|
requested = _validate_requested_formats(options.formats)
|
|
@@ -159,6 +164,7 @@ def build_project(options: BuildOptions) -> BuildResult:
|
|
|
159
164
|
|
|
160
165
|
|
|
161
166
|
def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
167
|
+
"""Load the project's model and check it without writing any artifacts."""
|
|
162
168
|
if not isinstance(options, ValidationOptions):
|
|
163
169
|
raise TypeError("validate_project expects ValidationOptions")
|
|
164
170
|
requested = _validate_requested_formats(options.formats)
|
|
@@ -182,6 +188,7 @@ def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
|
182
188
|
|
|
183
189
|
|
|
184
190
|
def clean_project(project_root: Path) -> None:
|
|
191
|
+
"""Remove the project's generated output folder."""
|
|
185
192
|
reject_nested_project_execution()
|
|
186
193
|
root = resolve_project_root(project_root)
|
|
187
194
|
config = load_project_config(root)
|
|
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
|
|
|
15
15
|
|
|
16
16
|
@dataclass(frozen=True, slots=True)
|
|
17
17
|
class BuildContext:
|
|
18
|
+
"""What ``build_model`` receives: the project root, its loaded ``config`` and source revision, with recorded read-only access to declared sources."""
|
|
18
19
|
project_root: Path
|
|
19
20
|
config: Any
|
|
20
21
|
source_revision: str | None
|
|
@@ -57,6 +58,7 @@ class BuildContext:
|
|
|
57
58
|
|
|
58
59
|
@dataclass(frozen=True, slots=True)
|
|
59
60
|
class DrawingContext:
|
|
61
|
+
"""What a drawing annotation provider receives: the built model and its sheets, in millimetres."""
|
|
60
62
|
project_root: Path
|
|
61
63
|
config: Any
|
|
62
64
|
model: DesignModel
|
{python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/__init__.py
RENAMED
|
@@ -19,6 +19,8 @@ type DrawingStyleToken = Literal[
|
|
|
19
19
|
|
|
20
20
|
@dataclass(frozen=True, slots=True)
|
|
21
21
|
class DrawingSheet:
|
|
22
|
+
"""One drawing view: its id, view kind, projection origin and axes, and projected bounds in millimetres."""
|
|
23
|
+
|
|
22
24
|
sheet_id: str
|
|
23
25
|
view_id: Literal["plan", "front", "side", "section"]
|
|
24
26
|
origin_mm: tuple[float, float, float]
|
|
@@ -29,6 +31,8 @@ class DrawingSheet:
|
|
|
29
31
|
|
|
30
32
|
@dataclass(frozen=True, slots=True)
|
|
31
33
|
class Line:
|
|
34
|
+
"""A straight annotation line on a sheet, in projected millimetres."""
|
|
35
|
+
|
|
32
36
|
id: str
|
|
33
37
|
sheet_id: str
|
|
34
38
|
start: Point2
|
|
@@ -38,6 +42,8 @@ class Line:
|
|
|
38
42
|
|
|
39
43
|
@dataclass(frozen=True, slots=True)
|
|
40
44
|
class Polyline:
|
|
45
|
+
"""An open or closed annotation polyline on a sheet, in projected millimetres."""
|
|
46
|
+
|
|
41
47
|
id: str
|
|
42
48
|
sheet_id: str
|
|
43
49
|
points: tuple[Point2, ...]
|
|
@@ -47,6 +53,8 @@ class Polyline:
|
|
|
47
53
|
|
|
48
54
|
@dataclass(frozen=True, slots=True)
|
|
49
55
|
class Text:
|
|
56
|
+
"""Annotation text placed on a sheet, with its height in millimetres and rotation in degrees."""
|
|
57
|
+
|
|
50
58
|
id: str
|
|
51
59
|
sheet_id: str
|
|
52
60
|
position: Point2
|
|
@@ -58,6 +66,8 @@ class Text:
|
|
|
58
66
|
|
|
59
67
|
@dataclass(frozen=True, slots=True)
|
|
60
68
|
class Dimension:
|
|
69
|
+
"""A labelled dimension between two sheet points, offset in millimetres."""
|
|
70
|
+
|
|
61
71
|
id: str
|
|
62
72
|
sheet_id: str
|
|
63
73
|
start: Point2
|
|
@@ -69,6 +79,8 @@ class Dimension:
|
|
|
69
79
|
|
|
70
80
|
@dataclass(frozen=True, slots=True)
|
|
71
81
|
class SectionCallout:
|
|
82
|
+
"""A section cut line on a sheet that refers to the sheet showing that section."""
|
|
83
|
+
|
|
72
84
|
id: str
|
|
73
85
|
sheet_id: str
|
|
74
86
|
start: Point2
|
|
@@ -80,6 +92,8 @@ class SectionCallout:
|
|
|
80
92
|
|
|
81
93
|
@dataclass(frozen=True, slots=True)
|
|
82
94
|
class ElevationMarker:
|
|
95
|
+
"""A marker on a sheet that refers to the sheet showing that elevation."""
|
|
96
|
+
|
|
83
97
|
id: str
|
|
84
98
|
sheet_id: str
|
|
85
99
|
position: Point2
|
|
@@ -90,12 +104,16 @@ class ElevationMarker:
|
|
|
90
104
|
|
|
91
105
|
@dataclass(frozen=True, slots=True)
|
|
92
106
|
class TableRow:
|
|
107
|
+
"""One row of an annotation ``Table``."""
|
|
108
|
+
|
|
93
109
|
id: str
|
|
94
110
|
cells: tuple[str, ...]
|
|
95
111
|
|
|
96
112
|
|
|
97
113
|
@dataclass(frozen=True, slots=True)
|
|
98
114
|
class Table:
|
|
115
|
+
"""A titled annotation table placed on a sheet."""
|
|
116
|
+
|
|
99
117
|
id: str
|
|
100
118
|
sheet_id: str
|
|
101
119
|
position: Point2
|
|
@@ -109,12 +127,16 @@ type AnnotationPrimitive = Line | Polyline | Text | Dimension | SectionCallout |
|
|
|
109
127
|
|
|
110
128
|
@dataclass(frozen=True, slots=True)
|
|
111
129
|
class SheetAnnotations:
|
|
130
|
+
"""All annotations for one sheet."""
|
|
131
|
+
|
|
112
132
|
sheet_id: str
|
|
113
133
|
annotations: tuple[AnnotationPrimitive, ...]
|
|
114
134
|
|
|
115
135
|
|
|
116
136
|
@dataclass(frozen=True, slots=True)
|
|
117
137
|
class DrawingAnnotationSet:
|
|
138
|
+
"""What a drawing annotation provider returns: annotations per sheet."""
|
|
139
|
+
|
|
118
140
|
provider_id: str
|
|
119
141
|
sheets: tuple[SheetAnnotations, ...]
|
|
120
142
|
|
|
@@ -15,6 +15,8 @@ GeometryKind = Literal["solid", "shell", "wire", "edge", "reference"]
|
|
|
15
15
|
|
|
16
16
|
@dataclass(frozen=True, slots=True)
|
|
17
17
|
class MaterialSpec:
|
|
18
|
+
"""A material: id, display name, category, RGB colour in 0-1 and optional density in kg/m3."""
|
|
19
|
+
|
|
18
20
|
id: str
|
|
19
21
|
name: str
|
|
20
22
|
category: str
|
|
@@ -25,12 +27,16 @@ class MaterialSpec:
|
|
|
25
27
|
|
|
26
28
|
@dataclass(frozen=True, slots=True)
|
|
27
29
|
class Placement:
|
|
30
|
+
"""An element's recorded position (millimetres) and XYZ rotation (degrees); it does not move the geometry, which must already be in place."""
|
|
31
|
+
|
|
28
32
|
translation_mm: tuple[float, float, float] = (0.0, 0.0, 0.0)
|
|
29
33
|
rotation_deg_xyz: tuple[float, float, float] = (0.0, 0.0, 0.0)
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
@dataclass(frozen=True, slots=True)
|
|
33
37
|
class Dimensions:
|
|
38
|
+
"""An element's declared size in millimetres; every value given must be finite and positive."""
|
|
39
|
+
|
|
34
40
|
length_mm: float | None = None
|
|
35
41
|
width_mm: float | None = None
|
|
36
42
|
height_mm: float | None = None
|
|
@@ -46,6 +52,8 @@ class Dimensions:
|
|
|
46
52
|
|
|
47
53
|
@dataclass(frozen=True, slots=True)
|
|
48
54
|
class IfcMapping:
|
|
55
|
+
"""The IFC class and predefined type an element exports as, or why it is excluded from IFC."""
|
|
56
|
+
|
|
49
57
|
ifc_class: str | None
|
|
50
58
|
predefined_type: str | None = None
|
|
51
59
|
exclude_reason: str | None = None
|
|
@@ -68,6 +76,8 @@ class Opening:
|
|
|
68
76
|
|
|
69
77
|
@dataclass(slots=True)
|
|
70
78
|
class DesignElement:
|
|
79
|
+
"""One model element with a stable id; physical elements need solid geometry and a material, and colours use RGB in 0-1."""
|
|
80
|
+
|
|
71
81
|
id: str
|
|
72
82
|
name: str
|
|
73
83
|
category: str
|
|
@@ -98,6 +108,8 @@ class DesignElement:
|
|
|
98
108
|
|
|
99
109
|
@dataclass(slots=True)
|
|
100
110
|
class DesignModel:
|
|
111
|
+
"""The whole model a project's ``build_model`` returns: its elements in millimetres, X right, Y away, Z up."""
|
|
112
|
+
|
|
101
113
|
id: str
|
|
102
114
|
name: str
|
|
103
115
|
artifact_stem: str
|
|
@@ -21,6 +21,7 @@ def box(
|
|
|
21
21
|
*,
|
|
22
22
|
origin: tuple[Length, Length, Length] | None = None,
|
|
23
23
|
) -> Solid:
|
|
24
|
+
"""Return a solid box length (X) by width (Y) by height (Z) with its minimum corner at ``origin`` (default the world origin), not its centre."""
|
|
24
25
|
_positive_lengths((length, width, height), "Box dimensions")
|
|
25
26
|
if origin is not None:
|
|
26
27
|
_point(origin, "Box origin")
|
|
@@ -42,6 +43,7 @@ def reference_line(
|
|
|
42
43
|
start: tuple[Length, Length, Length],
|
|
43
44
|
end: tuple[Length, Length, Length],
|
|
44
45
|
) -> Edge:
|
|
46
|
+
"""Return a straight edge from ``start`` to ``end`` for non-physical reference geometry."""
|
|
45
47
|
start_mm = _point(start, "Reference-line start")
|
|
46
48
|
end_mm = _point(end, "Reference-line end")
|
|
47
49
|
if start_mm == end_mm:
|
|
@@ -79,6 +81,7 @@ def prism_between(
|
|
|
79
81
|
width: Length,
|
|
80
82
|
height: Length,
|
|
81
83
|
) -> Solid:
|
|
84
|
+
"""Return a solid of ``width`` by ``height`` running from ``start`` to ``end``, with ``start`` as a bottom corner, width to the left of the run and height upward."""
|
|
82
85
|
_positive_lengths((width, height), "Prism dimensions")
|
|
83
86
|
start_mm = _point(start, "Prism start")
|
|
84
87
|
end_mm = _point(end, "Prism end")
|
|
@@ -103,6 +106,7 @@ def sloped_pool(
|
|
|
103
106
|
*,
|
|
104
107
|
origin: tuple[Length, Length, Length],
|
|
105
108
|
) -> Solid:
|
|
109
|
+
"""Return a pool body ``length`` along X and ``width`` along Y whose top edge starts at ``origin``, sloping from ``shallow_depth`` to ``deep_depth`` below it along X."""
|
|
106
110
|
_positive_lengths((length, width, shallow_depth, deep_depth), "Sloped-pool dimensions")
|
|
107
111
|
if to_mm(deep_depth) < to_mm(shallow_depth):
|
|
108
112
|
raise ModelValidationError("Sloped-pool deep depth must be at least the shallow depth")
|
|
@@ -124,6 +128,7 @@ def sloped_pool(
|
|
|
124
128
|
|
|
125
129
|
|
|
126
130
|
def bounds(shape: Any) -> tuple[float, float, float, float, float, float]:
|
|
131
|
+
"""Return a shape's bounding box as ``(xmin, ymin, zmin, xmax, ymax, zmax)`` in millimetres."""
|
|
127
132
|
box_value = shape.bounding_box()
|
|
128
133
|
return (
|
|
129
134
|
float(box_value.min.X),
|
|
@@ -136,6 +141,7 @@ def bounds(shape: Any) -> tuple[float, float, float, float, float, float]:
|
|
|
136
141
|
|
|
137
142
|
|
|
138
143
|
def combined_bounds(shapes: list[Any]) -> tuple[float, float, float, float, float, float]:
|
|
144
|
+
"""Return the bounding box of all ``shapes`` in millimetres (all zeros when empty)."""
|
|
139
145
|
values = [bounds(shape) for shape in shapes]
|
|
140
146
|
if not values:
|
|
141
147
|
return (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
|
@@ -176,6 +182,7 @@ def shared_tessellation() -> Iterator[None]:
|
|
|
176
182
|
|
|
177
183
|
|
|
178
184
|
def tessellate(shape: Any, linear_deflection: float, angular_deflection: float) -> tuple[list[list[float]], list[list[int]]]:
|
|
185
|
+
"""Return a shape's triangle mesh as ``(vertices, triangles)``, reusing one mesh per shape within a build."""
|
|
179
186
|
cache = _TESSELLATIONS.get()
|
|
180
187
|
key = (id(shape), float(linear_deflection), float(angular_deflection))
|
|
181
188
|
if cache is not None:
|
|
@@ -226,10 +233,12 @@ def single_wrapped_solid(shape: Any) -> Solid | None:
|
|
|
226
233
|
|
|
227
234
|
|
|
228
235
|
def is_valid_solid(shape: Any) -> bool:
|
|
236
|
+
"""Return whether ``shape`` is a valid build123d ``Solid`` with positive volume."""
|
|
229
237
|
return isinstance(shape, Solid) and bool(shape.is_valid) and float(shape.volume) > 0
|
|
230
238
|
|
|
231
239
|
|
|
232
240
|
def diagonal(bounds_value: tuple[float, float, float, float, float, float]) -> float:
|
|
241
|
+
"""Return the diagonal length of a ``bounds`` box in millimetres."""
|
|
233
242
|
return sqrt(sum((bounds_value[index + 3] - bounds_value[index]) ** 2 for index in range(3)))
|
|
234
243
|
|
|
235
244
|
|
|
@@ -9,6 +9,7 @@ from typing import overload
|
|
|
9
9
|
|
|
10
10
|
@dataclass(frozen=True, slots=True, order=True)
|
|
11
11
|
class Length:
|
|
12
|
+
"""A length stored in millimetres (``mm``); build values with ``mm``, ``inches``, ``feet`` or ``feet_inches`` and convert with ``to_mm``."""
|
|
12
13
|
mm: float
|
|
13
14
|
|
|
14
15
|
def __post_init__(self) -> None:
|
|
@@ -66,6 +67,7 @@ class Length:
|
|
|
66
67
|
|
|
67
68
|
@dataclass(frozen=True, slots=True)
|
|
68
69
|
class Area:
|
|
70
|
+
"""An area in square millimetres (``mm2``), the product of two ``Length`` values."""
|
|
69
71
|
mm2: float
|
|
70
72
|
|
|
71
73
|
def __post_init__(self) -> None:
|
|
@@ -91,6 +93,7 @@ class Area:
|
|
|
91
93
|
|
|
92
94
|
@dataclass(frozen=True, slots=True)
|
|
93
95
|
class Volume:
|
|
96
|
+
"""A volume in cubic millimetres (``mm3``), an ``Area`` times a ``Length``."""
|
|
94
97
|
mm3: float
|
|
95
98
|
|
|
96
99
|
def __post_init__(self) -> None:
|
|
@@ -111,50 +114,60 @@ FOOT = 12 * INCH
|
|
|
111
114
|
|
|
112
115
|
|
|
113
116
|
def to_mm(value: Length) -> float:
|
|
117
|
+
"""Return a ``Length`` as a float of millimetres, the geometry kernel's unit."""
|
|
114
118
|
if not isinstance(value, Length):
|
|
115
119
|
raise TypeError(f"Expected Length, got {type(value).__name__}")
|
|
116
120
|
return float(value.mm)
|
|
117
121
|
|
|
118
122
|
|
|
119
123
|
def mm(value: float) -> Length:
|
|
124
|
+
"""Return a ``Length`` of ``value`` millimetres."""
|
|
120
125
|
return value * MM
|
|
121
126
|
|
|
122
127
|
|
|
123
128
|
def inches(value: float) -> Length:
|
|
129
|
+
"""Return a ``Length`` of ``value`` inches."""
|
|
124
130
|
return value * INCH
|
|
125
131
|
|
|
126
132
|
|
|
127
133
|
def feet(value: float) -> Length:
|
|
134
|
+
"""Return a ``Length`` of ``value`` feet."""
|
|
128
135
|
return value * FOOT
|
|
129
136
|
|
|
130
137
|
|
|
131
138
|
def feet_inches(feet_value: float, inches_value: float = 0) -> Length:
|
|
139
|
+
"""Return a ``Length`` of ``feet_value`` feet plus ``inches_value`` inches."""
|
|
132
140
|
return feet_value * FOOT + inches_value * INCH
|
|
133
141
|
|
|
134
142
|
|
|
135
143
|
def square_feet(value: Area) -> float:
|
|
144
|
+
"""Return an ``Area`` in square feet."""
|
|
136
145
|
if not isinstance(value, Area):
|
|
137
146
|
raise TypeError("square_feet expects Area")
|
|
138
147
|
return value.mm2 / (304.8**2)
|
|
139
148
|
|
|
140
149
|
|
|
141
150
|
def cubic_feet(value: Volume) -> float:
|
|
151
|
+
"""Return a ``Volume`` in cubic feet."""
|
|
142
152
|
if not isinstance(value, Volume):
|
|
143
153
|
raise TypeError("cubic_feet expects Volume")
|
|
144
154
|
return value.mm3 / (304.8**3)
|
|
145
155
|
|
|
146
156
|
|
|
147
157
|
def cubic_yards(value: Volume) -> float:
|
|
158
|
+
"""Return a ``Volume`` in cubic yards."""
|
|
148
159
|
if not isinstance(value, Volume):
|
|
149
160
|
raise TypeError("cubic_yards expects Volume")
|
|
150
161
|
return value.mm3 / (914.4**3)
|
|
151
162
|
|
|
152
163
|
|
|
153
164
|
def metres(value: Length) -> float:
|
|
165
|
+
"""Return a ``Length`` in metres."""
|
|
154
166
|
return to_mm(value) / 1000.0
|
|
155
167
|
|
|
156
168
|
|
|
157
169
|
def square_metres(value: Area) -> float:
|
|
170
|
+
"""Return an ``Area`` in square metres."""
|
|
158
171
|
if not isinstance(value, Area):
|
|
159
172
|
raise TypeError("square_metres expects Area")
|
|
160
173
|
return value.mm2 / 1_000_000.0
|
|
@@ -50,6 +50,7 @@ _STABLE_ID = re.compile(r"[A-Za-z0-9._-]+\Z", re.ASCII)
|
|
|
50
50
|
|
|
51
51
|
@dataclass(frozen=True, slots=True)
|
|
52
52
|
class ValidationIssue:
|
|
53
|
+
"""One model or build problem: a code, ``warning`` or ``error`` severity, a message and where it applies."""
|
|
53
54
|
code: str
|
|
54
55
|
severity: Literal["warning", "error"]
|
|
55
56
|
message: str
|
|
File without changes
|
|
File without changes
|
{python_cad_tools-0.1.18 → python_cad_tools-0.1.19}/.github/workflows/downstream-compatibility.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|