python-cad-tools 0.1.17__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.17 → python_cad_tools-0.1.19}/.github/workflows/ci.yml +19 -28
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/CHANGELOG.md +42 -0
- {python_cad_tools-0.1.17/src/python_cad_tools.egg-info → python_cad_tools-0.1.19}/PKG-INFO +1 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/public-api.md +9 -7
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/spikes/curved-geometry-ifc-bounds.md +18 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/toolchain.md +3 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/artifacts.py +19 -8
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/build.py +10 -2
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/context.py +2 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/__init__.py +22 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/elements.py +12 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/ifc.py +3 -3
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/geometry.py +90 -15
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/manifests.py +38 -3
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/units.py +13 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/validation.py +17 -4
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19/src/python_cad_tools.egg-info}/PKG-INFO +1 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/scm_file_list.json +2 -0
- python_cad_tools-0.1.19/src/python_cad_tools.egg-info/scm_version.json +8 -0
- python_cad_tools-0.1.17/src/python_cad_tools.egg-info/scm_version.json +0 -8
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.gitattributes +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.githooks/pre-push +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.github/workflows/downstream-compatibility.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.github/workflows/release-candidate.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.github/workflows/release.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.gitignore +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.opencode/commands/autocommit.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.opencode/tools/specrepo-autocommit.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/.opencode/tools/specrepo-autocommit.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/AGENTS.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/CLAUDE.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/LICENSE +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/MANIFEST.in +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/README.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/build-semantics.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/drawing-extensions.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/manifests.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/neutral-model.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/project-configuration.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/spikes/format-feasibility.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/two-tier-contract.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/viewer-delivery.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/pyproject.toml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/setup.cfg +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/__main__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_locking.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_project_loader.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_project_state.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_scaffold.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_transaction.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/app.webmanifest +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/asset-manifest.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/animationGroup-CMgMiFPo.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bakedVertexAnimation-BlpwZEna.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/basisTextureLoader-pxgVvwE7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/brdfTextureTools-CL1Nnrm1.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpFragment-BNBjNOnF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpVertex-BTawYPw8.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/bumpVertexDeclaration-B_fffQFY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/clipPlaneFragment-D1ZAafqO.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/clipPlaneVertex-BC_wnvpq.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/cubemapToSphericalPolynomial-DeA9LJ87.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/dds-C5zm4fz8.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/ddsTextureLoader-DsS5rL5j.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/default.fragment-BUHDudIn.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/default.vertex-B80Wq2Ab.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/defaultUboDeclaration-DuGcl3VN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/dumpTools-1F1Rx0a0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/envTextureLoader-DqI1ceC5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/exrTextureLoader-DmNwF2B5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyForceBlock-DmvfeucL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyImpulseBlock-ChgIpPqh.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphArrayIndexBlock-_JwXSrlj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBezierCurveEasingBlock-B-T0qVRw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBinaryOperationBlock-TpZm5BfV.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphBranchBlock-CNwAs8cP.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCachedOperationBlock-DaEYpjja.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCancelDelayBlock-Dc4RKYSf.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCodeExecutionBlock-DCxeE8wr.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConditionalDataBlock-TckZ2SGl.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConsoleLogBlock-B5e69wX5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphConstantBlock-3ktOI1lC.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphContextBlock-XTBtETD_.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphCounterBlock-Pb64y9OD.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDataSwitchBlock-DsG4QDCF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDebounceBlock-B_XjPDoZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDebugBlock-CD6lTvpS.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphDoNBlock-0NvER8W0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphEasingBlock-B6hapywt.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphFlipFlopBlock-D1uyBOpq.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphForLoopBlock-BYD81Gof.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphFunctionReferenceBlock-zABkEq-X.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGLTFDataProvider-B0ofoVrD.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAngularVelocityBlock-DPTUNnTb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAssetBlock-B8_99mSz.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetLinearVelocityBlock-DFYXgPrA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPhysicsMassPropertiesBlock-DA6AqPR7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPropertyBlock-Bp4o9QmW.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetSoundVolumeBlock-BAmdegmU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphGetVariableBlock-Cd8Y6leR.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIndexOfBlock-CGYxKZZY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphInterpolationBlock-CwjeWPr7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIsKeyPressedBlock-rNAEqrST.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphIsSoundPlayingBlock-BTztAQ_0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphJsonPointerParserBlock-DoLWKXUb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyDownEventBlock-DPIi37WK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyUpEventBlock-ZV1Tim4d.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyboardEventBlock-ClUSFYDa.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMathBlocks-BEiYY5fC.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMathCombineExtractBlocks-CVfFjT4m.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMatrixMathBlocks-B6l0dCDc.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMeshPickEventBlock-kdpuo1mU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphMultiGateBlock-n99NMOON.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseAnimationBlock-DXKPP4nK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseSoundBlock-e2k4W8Bc.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPhysicsCollisionEventBlock-ClgKwXfJ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPlayAnimationBlock-BZj6MNgX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPlaySoundBlock-BnzlrpjK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerDownEventBlock-CQiX1RZi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerMoveEventBlock-B_JzBfd9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOutEventBlock-B-xKCRP6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOverEventBlock-DPC5GKft.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerUpEventBlock-hCR14WZY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphReceiveCustomEventBlock-EOc5SmbK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneReadyEventBlock-BAOJ-S5R.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneTickEventBlock-BJla1nDw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSendCustomEventBlock-CbJzCBSw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSequenceBlock-C0E5Vhwk.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetAngularVelocityBlock-Crx1sltA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetDelayBlock-t-D4JM8I.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetLinearVelocityBlock-DKNa-lhN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPhysicsMotionTypeBlock-BIeMWJwi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPropertyBlock-CFERwfo5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetSoundVolumeBlock-B8fGBso9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSetVariableBlock-D3NUXLsU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSoundEndedEventBlock-BsojQIIQ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphStopAnimationBlock-Bhvi4mzM.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphStopSoundBlock-BL-vDlPP.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphSwitchBlock-q5uox2Ll.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphThrottleBlock-ZvIobaF-.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphTransformCoordinatesSystemBlock-DC7IZTrj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphTypeToTypeBlocks-DsmLuQmd.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphUnaryOperationBlock-CeFOvM8N.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphVectorMathBlocks-O_o0PB3R.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphWaitAllBlock-CS8S_sto.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/flowGraphWhileLoopBlock-BogzY-TI.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/fogFragment-5iY5mDF9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-CzELCfrg.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-Dm4qQcCl.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-Dl5Knagi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-gV6NfBr2.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BU7N8GWm.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BYh0LKwp.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DGCqlu5B.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DPRpU6I6.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.vertex-DVVqYQkj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.fragment-CJ5P29rW.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/geometry.vertex-D8aj2PHd.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowBlurPostProcess.fragment-BNUj6Ok4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.fragment-BMfCbDSO.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.vertex-HFoIGtvW.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.fragment-DcbXX8O5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.vertex-C6kfp5Df.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/harmonicsFunctions-B_Rux4W4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/hdrTextureLoader-BGQvgh0h.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/helperFunctions-DfEEUVrK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/iesTextureLoader-DRIv8q-c.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/index-Bi_hQlRi.css +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/index-QUv88KPb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlur.fragment-AIxPvzg7.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → 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.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-0MaBFn29.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-CKf1P4fb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/ktxTextureLoader-tKPsUacI.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/lightFragment-k2nRX45x.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/logDepthDeclaration-BGXXcOUJ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/logDepthVertex-BC72KyzN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/mainUVVaryingDeclaration-BCMZuxRE.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/meshUboDeclaration-Cxk75_zo.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/oitFragment-BtwWIihL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-8rnUKL54.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-C6yWZfQI.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbr.vertex-DbnVIs8Y.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrMaterial.pure-CFHhabYh.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrMaterialLoadingAdapter-BQGAj-f6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-BMK7l2Ba.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-DNsGu5u0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-Cd1JAAAL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-rBzbf9n3.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/packingFunctions-Dji1Rr-b.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/packingFunctions-_goA4OEm.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pass.fragment-CgGToehX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-CqqQ20XF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-D93dlgjG.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbr.fragment-YSvcDJjz.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbr.vertex-BOhSAeHX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrBRDFFunctions-DTEwurLZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrDebug-B4IzJZHZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrIBLFunctions-gJ0KErMb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrMaterial.pure-BRIxFz02.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrMaterialLoadingAdapter--NRrZRBU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/pbrUboDeclaration-6dxbcrtA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/postprocess.vertex-ZxthID8t.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/procedural.vertex-BSVnGss-.js +0 -0
- {python_cad_tools-0.1.17 → 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.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/reflectionFunction-CgKY-0t6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdDecode.fragment-CAfeJDpQ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-D7xEO0B-.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-DIzz0LC4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/sceneUboDeclaration-kGrRDglr.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-CgQTw0M7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-DnEEx4Gs.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/tgaTextureLoader-CwaQqeYn.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/assets/vertexColorMixing-C2cK_vck.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/favicon.svg +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/index.html +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/_viewer_static/sw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/build-info.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/cli.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/determinism.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/_catalog.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/drawings/_validation.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exceptions.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/base.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/annotations.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/dxf.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/model.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/pdf.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/primitives.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/projection.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/drawings/svg.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/glb.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/quantities.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/exporters/step.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/project_config.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/py.typed +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/recipes.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/runtime_sync.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/build-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/design-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/download-manifest-2.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/drawing-annotations-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/glb-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/ifc-validation-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/quantities-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/run-metadata-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/site-metadata-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/schemas/step-validation-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/site.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/.gitignore +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/README.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/config.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/drawing_annotations.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/generated/.gitkeep +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/model.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools/templates/project/pyproject.toml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/SOURCES.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/dependency_links.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/entry_points.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/src/python_cad_tools.egg-info/requires.txt +0 -0
- {python_cad_tools-0.1.17 → 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,48 @@ 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
|
+
|
|
28
|
+
## [0.1.18] - 2026-10-08
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Curved B-rep solids (spheres, `cylinder_between` cylinders and other curved
|
|
33
|
+
shapes) no longer fail `build` and `verify` with `artifact_integrity:
|
|
34
|
+
IFC/design bounds mismatch`. The design manifest records each element's
|
|
35
|
+
`body_bounds_mm` (the bounds of the body IFC actually writes: the mesh of a
|
|
36
|
+
tessellated solid, the exact shape for recipes), and the IFC check compares
|
|
37
|
+
against it at the same `1e-6` tolerance. Manifests without the field fall
|
|
38
|
+
back to `bounds_mm`. `body_bounds_mm` describes the export, not the design,
|
|
39
|
+
so it is left out of `semantic_hash`: design hashes are unchanged, and
|
|
40
|
+
`validate` does not tessellate.
|
|
41
|
+
- `validate` reports a build123d `Part` (or compound) that holds one solid as
|
|
42
|
+
`solid-wrapped` with the fix (`.solid()`), instead of a bare
|
|
43
|
+
`solid-invalid`.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- A build tessellates each element once and shares the mesh between the
|
|
48
|
+
design manifest, IFC and GLB (`geometry.shared_tessellation`), instead of
|
|
49
|
+
IFC and GLB each meshing it. `benge-property-cad`'s full build went from
|
|
50
|
+
106 s to 67 s on the owner's Mac.
|
|
51
|
+
|
|
10
52
|
## [0.1.16] - 2026-09-22
|
|
11
53
|
|
|
12
54
|
### Fixed
|
|
@@ -16,13 +16,15 @@ of optional runtime imports.
|
|
|
16
16
|
`cubic_yards`, `metres`, and `square_metres`.
|
|
17
17
|
- `python_cad_tools.geometry`: `box`, `reference_line`, `cylinder_between`,
|
|
18
18
|
`prism_between`, `sloped_pool`, `bounds`, `combined_bounds`, `tessellate`,
|
|
19
|
-
`is_valid_solid`, and `diagonal`.
|
|
20
|
-
build
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
|
|
25
|
-
`
|
|
19
|
+
`is_valid_solid`, and `diagonal`. Curved B-rep solids (`cylinder_between`,
|
|
20
|
+
build123d spheres and other curved shapes) build and verify: IFC writes
|
|
21
|
+
them as triangle meshes, and the IFC bounds check compares that mesh with
|
|
22
|
+
the same tessellation recorded in the design manifest as `body_bounds_mm`
|
|
23
|
+
(0.1.18). Use `python_cad_tools.recipes`' `CircleProfile` +
|
|
24
|
+
`ExtrudedProfile` where an analytic IFC body is wanted instead of a mesh.
|
|
25
|
+
Pass a `Solid`: build123d algebra-mode shapes such as `Sphere(...)` are a
|
|
26
|
+
`Part` wrapping one solid, which `validate` reports as `solid-wrapped`
|
|
27
|
+
(use `.solid()`).
|
|
26
28
|
- `python_cad_tools.drawings`: `Point2`, `Direction`, `DrawingStyleToken`,
|
|
27
29
|
`DrawingSheet`, `Line`, `Polyline`, `Text`, `Dimension`, `SectionCallout`,
|
|
28
30
|
`ElevationMarker`, `TableRow`, `Table`, `SheetAnnotations`, and
|
{python_cad_tools-0.1.17 → python_cad_tools-0.1.19}/docs/spikes/curved-geometry-ifc-bounds.md
RENAMED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
# Curved geometry vs. the IFC/design bounds integrity check
|
|
1
|
+
# Curved geometry vs. the IFC/design bounds integrity check
|
|
2
|
+
|
|
3
|
+
**Resolved in 0.1.18 (2026-10-08).** The mechanism is confirmed in source:
|
|
4
|
+
elements without a recipe are written to IFC as an `IfcTriangulatedFaceSet`
|
|
5
|
+
from `tessellate(geometry, 0.5, 0.25)`, the IFC report's bounds are read back
|
|
6
|
+
from those mesh coordinates, and the manifest recorded only the exact B-rep
|
|
7
|
+
bounds; `_reconcile_formats` compared the two at `1e-6`. The fix is candidate
|
|
8
|
+
direction 1 below ("compare like with like"): the design manifest now records
|
|
9
|
+
`body_bounds_mm`, the bounds of the same tessellation
|
|
10
|
+
(`geometry.IFC_TESSELLATION`, shared with the exporter), and the IFC check
|
|
11
|
+
compares against it, still exactly. A live hosted run on 2026-10-08 ("change
|
|
12
|
+
the cube to a sphere", `Sphere(152.4).solid()`) failed with x/y short by
|
|
13
|
+
0.58 mm before the fix; `tests/integration/test_curved_geometry.py` covers a
|
|
14
|
+
sphere, a `cylinder_between` cylinder, a box, and a tampered IFC report.
|
|
15
|
+
Approval: `specrepo/approved/2026-10-08-curved-geometry-ifc-bounds/` (workspace).
|
|
16
|
+
|
|
17
|
+
The history below is kept as it was written.
|
|
18
|
+
|
|
2
19
|
|
|
3
20
|
Status: **mechanism confirmed, fix known — not yet verified against this
|
|
4
21
|
repo's own source.** A later sandbox-agent attempt on the same project (see
|
|
@@ -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
|
|
@@ -14,7 +14,7 @@ from xml.etree import ElementTree
|
|
|
14
14
|
|
|
15
15
|
from .determinism import semantic_hash, sha256_file
|
|
16
16
|
from .exceptions import ArtifactIntegrityError, BuildExportError
|
|
17
|
-
from .manifests import load_json_document, validate_json_document
|
|
17
|
+
from .manifests import design_semantic_projection, load_json_document, validate_json_document
|
|
18
18
|
from .validation import ValidationIssue
|
|
19
19
|
|
|
20
20
|
BUILD_MANIFEST_RELATIVE = "manifests/build-manifest.json"
|
|
@@ -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}")
|
|
@@ -153,9 +158,8 @@ def verify_output_root(output_root: Path, project_root: Path | None = None) -> V
|
|
|
153
158
|
_verify_sources(project_root, document)
|
|
154
159
|
selected = _selected_formats(document)
|
|
155
160
|
design = load_design_manifest(output_root / "manifests/design-manifest.json")
|
|
156
|
-
|
|
157
|
-
recorded_design_hash
|
|
158
|
-
if recorded_design_hash != semantic_hash(design_without_hash):
|
|
161
|
+
recorded_design_hash = design.get("semantic_hash")
|
|
162
|
+
if recorded_design_hash != semantic_hash(design_semantic_projection(design)):
|
|
159
163
|
raise ArtifactIntegrityError("Design manifest semantic_hash does not reproduce")
|
|
160
164
|
if document["design_semantic_hash"] != design["semantic_hash"]:
|
|
161
165
|
raise ArtifactIntegrityError("Build and design manifest semantic hashes disagree")
|
|
@@ -172,6 +176,7 @@ def verify_output_root(output_root: Path, project_root: Path | None = None) -> V
|
|
|
172
176
|
|
|
173
177
|
|
|
174
178
|
def verify_build_output(project_root: Path) -> VerificationResult:
|
|
179
|
+
"""Check that a project's generated output still matches its build manifest."""
|
|
175
180
|
from ._locking import project_lock
|
|
176
181
|
from ._transaction import recover_promotion
|
|
177
182
|
from .project_config import load_project_config, output_path, resolve_project_root
|
|
@@ -185,6 +190,7 @@ def verify_build_output(project_root: Path) -> VerificationResult:
|
|
|
185
190
|
|
|
186
191
|
|
|
187
192
|
def get_package_build_info() -> PackageBuildInfo:
|
|
193
|
+
"""Return the installed distribution's build information."""
|
|
188
194
|
try:
|
|
189
195
|
document = json.loads(resources.files("python_cad_tools").joinpath("build-info.json").read_text(encoding="utf-8"))
|
|
190
196
|
except (FileNotFoundError, json.JSONDecodeError) as error:
|
|
@@ -386,7 +392,11 @@ def _reconcile_formats(root: Path, formats: tuple[str, ...]) -> None:
|
|
|
386
392
|
for item in elements
|
|
387
393
|
if item["physical"] and "ifc" in item["export_formats"] and item["ifc_class"] is not None
|
|
388
394
|
]
|
|
389
|
-
|
|
395
|
+
# Tessellated IFC bodies are meshes; compare them with the same mesh, recorded in the
|
|
396
|
+
# manifest as body_bounds_mm (0.1.18). Older manifests fall back to the exact bounds.
|
|
397
|
+
_require_matching_bounds(
|
|
398
|
+
"IFC", report["bounds_mm"], _combined_manifest_bounds(expected_elements, key="body_bounds_mm")
|
|
399
|
+
)
|
|
390
400
|
_reconcile_ifc_extensions(root, formats, report, expected_elements)
|
|
391
401
|
if "glb" in formats:
|
|
392
402
|
from .exporters.glb import glb_json
|
|
@@ -536,14 +546,15 @@ def _normalized_text(value: str) -> str:
|
|
|
536
546
|
return " ".join(value.split())
|
|
537
547
|
|
|
538
548
|
|
|
539
|
-
def _combined_manifest_bounds(elements: list[dict[str, Any]]) -> list[float]:
|
|
549
|
+
def _combined_manifest_bounds(elements: list[dict[str, Any]], key: str = "bounds_mm") -> list[float]:
|
|
540
550
|
if not elements:
|
|
541
551
|
return [0.0] * 6
|
|
552
|
+
values = [item.get(key) or item["bounds_mm"] for item in elements]
|
|
542
553
|
return [
|
|
543
|
-
round(min(float(
|
|
554
|
+
round(min(float(value[index]) for value in values), 6)
|
|
544
555
|
for index in range(3)
|
|
545
556
|
] + [
|
|
546
|
-
round(max(float(
|
|
557
|
+
round(max(float(value[index]) for value in values), 6)
|
|
547
558
|
for index in range(3, 6)
|
|
548
559
|
]
|
|
549
560
|
|
|
@@ -22,6 +22,7 @@ from .determinism import semantic_hash, sha256_file, write_json
|
|
|
22
22
|
from .exceptions import BuildExportError, ModelValidationError, ProjectConfigError, UnsafePathError
|
|
23
23
|
from .exporters import GlbExporter, IfcExporter, QuantityExporter, StepExporter
|
|
24
24
|
from .exporters.drawings import DrawingExporter
|
|
25
|
+
from .geometry import shared_tessellation
|
|
25
26
|
from .manifests import build_manifest_document, design_manifest, write_preinventory_manifests
|
|
26
27
|
from .project_config import FORMAT_ORDER, load_project_config, output_path, resolve_project_root
|
|
27
28
|
from .validation import ValidationIssue, fatal_issues
|
|
@@ -31,18 +32,21 @@ type FormatName = Literal["step", "ifc", "glb", "drawings", "quantities"]
|
|
|
31
32
|
|
|
32
33
|
@dataclass(frozen=True, slots=True)
|
|
33
34
|
class BuildOptions:
|
|
35
|
+
"""Options for ``build_project``: the project root and the formats to build (default: the project's own)."""
|
|
34
36
|
project_root: Path
|
|
35
37
|
formats: tuple[FormatName, ...] | None = None
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
@dataclass(frozen=True, slots=True)
|
|
39
41
|
class ValidationOptions:
|
|
42
|
+
"""Options for ``validate_project``: the project root and the formats to check (default: the project's own)."""
|
|
40
43
|
project_root: Path
|
|
41
44
|
formats: tuple[FormatName, ...] | None = None
|
|
42
45
|
|
|
43
46
|
|
|
44
47
|
@dataclass(frozen=True, slots=True)
|
|
45
48
|
class BuildResult:
|
|
49
|
+
"""What ``build_project`` produced: its output folder, artifacts, build manifest and hashes."""
|
|
46
50
|
project_root: Path
|
|
47
51
|
output_root: Path
|
|
48
52
|
formats: tuple[FormatName, ...]
|
|
@@ -56,6 +60,7 @@ class BuildResult:
|
|
|
56
60
|
|
|
57
61
|
@dataclass(frozen=True, slots=True)
|
|
58
62
|
class ValidationReport:
|
|
63
|
+
"""The issues ``validate_project`` found; ``ok`` is true when none is fatal."""
|
|
59
64
|
project_root: Path
|
|
60
65
|
formats: tuple[FormatName, ...]
|
|
61
66
|
issues: tuple[ValidationIssue, ...]
|
|
@@ -78,11 +83,12 @@ EXPORTERS: dict[str, type[Any]] = {
|
|
|
78
83
|
|
|
79
84
|
|
|
80
85
|
def build_project(options: BuildOptions) -> BuildResult:
|
|
86
|
+
"""Build the project's requested formats into its output folder and return the result."""
|
|
81
87
|
if not isinstance(options, BuildOptions):
|
|
82
88
|
raise TypeError("build_project expects BuildOptions")
|
|
83
89
|
requested = _validate_requested_formats(options.formats)
|
|
84
90
|
root = resolve_project_root(options.project_root)
|
|
85
|
-
with project_execution():
|
|
91
|
+
with project_execution(), shared_tessellation():
|
|
86
92
|
with project_lock(root):
|
|
87
93
|
config = load_project_config(root)
|
|
88
94
|
formats = config.default_formats if requested is None else requested
|
|
@@ -158,6 +164,7 @@ def build_project(options: BuildOptions) -> BuildResult:
|
|
|
158
164
|
|
|
159
165
|
|
|
160
166
|
def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
167
|
+
"""Load the project's model and check it without writing any artifacts."""
|
|
161
168
|
if not isinstance(options, ValidationOptions):
|
|
162
169
|
raise TypeError("validate_project expects ValidationOptions")
|
|
163
170
|
requested = _validate_requested_formats(options.formats)
|
|
@@ -173,7 +180,7 @@ def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
|
173
180
|
formats=formats,
|
|
174
181
|
issues=loaded.issues,
|
|
175
182
|
source_set_hash=source_set_hash,
|
|
176
|
-
design_semantic_hash=design_manifest(loaded.model)["semantic_hash"],
|
|
183
|
+
design_semantic_hash=design_manifest(loaded.model, include_body_bounds=False)["semantic_hash"],
|
|
177
184
|
annotation_provider_id=(
|
|
178
185
|
None if loaded.annotations is None else loaded.annotations.provider_id
|
|
179
186
|
),
|
|
@@ -181,6 +188,7 @@ def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
|
181
188
|
|
|
182
189
|
|
|
183
190
|
def clean_project(project_root: Path) -> None:
|
|
191
|
+
"""Remove the project's generated output folder."""
|
|
184
192
|
reject_nested_project_execution()
|
|
185
193
|
root = resolve_project_root(project_root)
|
|
186
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.17 → 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
|
|
@@ -17,7 +17,7 @@ from ifcopenshell import ifcopenshell_wrapper
|
|
|
17
17
|
from ..determinism import normalized_build_epoch, write_json
|
|
18
18
|
from ..elements import DesignElement, Opening
|
|
19
19
|
from ..exceptions import BuildExportError, ModelValidationError
|
|
20
|
-
from ..geometry import bounds, tessellate
|
|
20
|
+
from ..geometry import IFC_TESSELLATION, bounds, tessellate
|
|
21
21
|
from ..recipes import (
|
|
22
22
|
CircleProfile,
|
|
23
23
|
DifferenceRecipe,
|
|
@@ -326,7 +326,7 @@ def _build_representation(file, context, element: DesignElement) -> tuple[Any, s
|
|
|
326
326
|
BREP instead.
|
|
327
327
|
"""
|
|
328
328
|
if element.recipe is None:
|
|
329
|
-
vertices, triangles = tessellate(element.geometry,
|
|
329
|
+
vertices, triangles = tessellate(element.geometry, *IFC_TESSELLATION)
|
|
330
330
|
points = file.createIfcCartesianPointList3D(vertices)
|
|
331
331
|
face_set = file.createIfcTriangulatedFaceSet(
|
|
332
332
|
points,
|
|
@@ -482,7 +482,7 @@ def _add_opening(file, context, host_product, storey, element, opening: Opening)
|
|
|
482
482
|
The host element's ``geometry`` stays authoritative for every other
|
|
483
483
|
format; the framework does not boolean-subtract the opening.
|
|
484
484
|
"""
|
|
485
|
-
vertices, triangles = tessellate(opening.geometry,
|
|
485
|
+
vertices, triangles = tessellate(opening.geometry, *IFC_TESSELLATION)
|
|
486
486
|
points = file.createIfcCartesianPointList3D(vertices)
|
|
487
487
|
face_set = file.createIfcTriangulatedFaceSet(
|
|
488
488
|
points, None, True, [[index + 1 for index in triangle] for triangle in triangles], None
|