python-cad-tools 0.1.17__tar.gz → 0.1.18__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.18}/CHANGELOG.md +24 -0
- {python_cad_tools-0.1.17/src/python_cad_tools.egg-info → python_cad_tools-0.1.18}/PKG-INFO +1 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/public-api.md +9 -7
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/spikes/curved-geometry-ifc-bounds.md +18 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/artifacts.py +12 -8
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/build.py +3 -2
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/ifc.py +3 -3
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/geometry.py +81 -15
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/manifests.py +38 -3
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/validation.py +16 -4
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18/src/python_cad_tools.egg-info}/PKG-INFO +1 -1
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/scm_file_list.json +2 -0
- python_cad_tools-0.1.18/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.18}/.gitattributes +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.githooks/pre-push +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.github/workflows/ci.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.github/workflows/downstream-compatibility.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.github/workflows/release-candidate.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.github/workflows/release.yml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.gitignore +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.opencode/commands/autocommit.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.opencode/tools/specrepo-autocommit.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.opencode/tools/specrepo-autocommit.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/AGENTS.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/CLAUDE.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/LICENSE +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/MANIFEST.in +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/README.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/build-semantics.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/drawing-extensions.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/manifests.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/neutral-model.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/project-configuration.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/spikes/format-feasibility.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/toolchain.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/two-tier-contract.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/docs/viewer-delivery.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/pyproject.toml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/setup.cfg +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/__main__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_locking.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_project_loader.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_project_state.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_scaffold.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_transaction.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/app.webmanifest +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/asset-manifest.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/animationGroup-CMgMiFPo.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/bakedVertexAnimation-BlpwZEna.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/basisTextureLoader-pxgVvwE7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/brdfTextureTools-CL1Nnrm1.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/bumpFragment-BNBjNOnF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/bumpVertex-BTawYPw8.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/bumpVertexDeclaration-B_fffQFY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/clipPlaneFragment-D1ZAafqO.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/clipPlaneVertex-BC_wnvpq.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/cubemapToSphericalPolynomial-DeA9LJ87.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/dds-C5zm4fz8.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/src/python_cad_tools/_viewer_static/assets/ddsTextureLoader-DsS5rL5j.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/default.fragment-BUHDudIn.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/default.vertex-B80Wq2Ab.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/defaultUboDeclaration-DuGcl3VN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/dumpTools-1F1Rx0a0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/envTextureLoader-DqI1ceC5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/exrTextureLoader-DmNwF2B5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyForceBlock-DmvfeucL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphApplyImpulseBlock-ChgIpPqh.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphArrayIndexBlock-_JwXSrlj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphBezierCurveEasingBlock-B-T0qVRw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphBinaryOperationBlock-TpZm5BfV.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphBranchBlock-CNwAs8cP.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphCachedOperationBlock-DaEYpjja.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphCancelDelayBlock-Dc4RKYSf.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphCodeExecutionBlock-DCxeE8wr.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphConditionalDataBlock-TckZ2SGl.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphConsoleLogBlock-B5e69wX5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphConstantBlock-3ktOI1lC.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphContextBlock-XTBtETD_.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphCounterBlock-Pb64y9OD.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphDataSwitchBlock-DsG4QDCF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphDebounceBlock-B_XjPDoZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphDebugBlock-CD6lTvpS.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphDoNBlock-0NvER8W0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphEasingBlock-B6hapywt.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphFlipFlopBlock-D1uyBOpq.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphForLoopBlock-BYD81Gof.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphFunctionReferenceBlock-zABkEq-X.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGLTFDataProvider-B0ofoVrD.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAngularVelocityBlock-DPTUNnTb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetAssetBlock-B8_99mSz.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetLinearVelocityBlock-DFYXgPrA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPhysicsMassPropertiesBlock-DA6AqPR7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetPropertyBlock-Bp4o9QmW.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetSoundVolumeBlock-BAmdegmU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphGetVariableBlock-Cd8Y6leR.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphIndexOfBlock-CGYxKZZY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphInterpolationBlock-CwjeWPr7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphIsKeyPressedBlock-rNAEqrST.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphIsSoundPlayingBlock-BTztAQ_0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphJsonPointerParserBlock-DoLWKXUb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyDownEventBlock-DPIi37WK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyUpEventBlock-ZV1Tim4d.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphKeyboardEventBlock-ClUSFYDa.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphMathBlocks-BEiYY5fC.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphMathCombineExtractBlocks-CVfFjT4m.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphMatrixMathBlocks-B6l0dCDc.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphMeshPickEventBlock-kdpuo1mU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphMultiGateBlock-n99NMOON.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseAnimationBlock-DXKPP4nK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPauseSoundBlock-e2k4W8Bc.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPhysicsCollisionEventBlock-ClgKwXfJ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPlayAnimationBlock-BZj6MNgX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPlaySoundBlock-BnzlrpjK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerDownEventBlock-CQiX1RZi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerMoveEventBlock-B_JzBfd9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOutEventBlock-B-xKCRP6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerOverEventBlock-DPC5GKft.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphPointerUpEventBlock-hCR14WZY.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphReceiveCustomEventBlock-EOc5SmbK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneReadyEventBlock-BAOJ-S5R.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSceneTickEventBlock-BJla1nDw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSendCustomEventBlock-CbJzCBSw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSequenceBlock-C0E5Vhwk.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetAngularVelocityBlock-Crx1sltA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetDelayBlock-t-D4JM8I.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetLinearVelocityBlock-DKNa-lhN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPhysicsMotionTypeBlock-BIeMWJwi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetPropertyBlock-CFERwfo5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetSoundVolumeBlock-B8fGBso9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSetVariableBlock-D3NUXLsU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSoundEndedEventBlock-BsojQIIQ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphStopAnimationBlock-Bhvi4mzM.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphStopSoundBlock-BL-vDlPP.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphSwitchBlock-q5uox2Ll.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphThrottleBlock-ZvIobaF-.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphTransformCoordinatesSystemBlock-DC7IZTrj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphTypeToTypeBlocks-DsmLuQmd.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphUnaryOperationBlock-CeFOvM8N.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphVectorMathBlocks-O_o0PB3R.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphWaitAllBlock-CS8S_sto.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/flowGraphWhileLoopBlock-BogzY-TI.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/fogFragment-5iY5mDF9.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-CzELCfrg.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting-Dm4qQcCl.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-Dl5Knagi.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.fragment-gV6NfBr2.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BU7N8GWm.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplatting.vertex-BYh0LKwp.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DGCqlu5B.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.fragment-DPRpU6I6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/src/python_cad_tools/_viewer_static/assets/gaussianSplattingVoxel.vertex-DVVqYQkj.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/geometry.fragment-CJ5P29rW.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/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.18}/src/python_cad_tools/_viewer_static/assets/geometry.vertex-D8aj2PHd.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/glowBlurPostProcess.fragment-BNUj6Ok4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.fragment-BMfCbDSO.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/glowMapGeneration.vertex-HFoIGtvW.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.fragment-DcbXX8O5.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/glowMapMerge.vertex-C6kfp5Df.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/harmonicsFunctions-B_Rux4W4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/hdrTextureLoader-BGQvgh0h.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/helperFunctions-DfEEUVrK.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/iesTextureLoader-DRIv8q-c.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/index-Bi_hQlRi.css +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/index-QUv88KPb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/kernelBlur.fragment-AIxPvzg7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/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.18}/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.18}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-0MaBFn29.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/kernelBlurVaryingDeclaration-CKf1P4fb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/ktxTextureLoader-tKPsUacI.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/lightFragment-k2nRX45x.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/logDepthDeclaration-BGXXcOUJ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/logDepthVertex-BC72KyzN.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/mainUVVaryingDeclaration-BCMZuxRE.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/src/python_cad_tools/_viewer_static/assets/meshUboDeclaration-Cxk75_zo.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/oitFragment-BtwWIihL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-8rnUKL54.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbr.fragment-C6yWZfQI.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/src/python_cad_tools/_viewer_static/assets/openpbr.vertex-DbnVIs8Y.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrMaterial.pure-CFHhabYh.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrMaterialLoadingAdapter-BQGAj-f6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-BMK7l2Ba.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrTransmissionLayerData-DNsGu5u0.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-Cd1JAAAL.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/openpbrUboDeclaration-rBzbf9n3.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/packingFunctions-Dji1Rr-b.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/packingFunctions-_goA4OEm.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pass.fragment-CgGToehX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-CqqQ20XF.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/passCube.fragment-D93dlgjG.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbr.fragment-YSvcDJjz.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbr.vertex-BOhSAeHX.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrBRDFFunctions-DTEwurLZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrDebug-B4IzJZHZ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrIBLFunctions-gJ0KErMb.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrMaterial.pure-BRIxFz02.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrMaterialLoadingAdapter--NRrZRBU.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/pbrUboDeclaration-6dxbcrtA.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/postprocess.vertex-ZxthID8t.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/procedural.vertex-BSVnGss-.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/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.18}/src/python_cad_tools/_viewer_static/assets/reflectionFunction-CgKY-0t6.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/rgbdDecode.fragment-CAfeJDpQ.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-D7xEO0B-.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/rgbdEncode.fragment-DIzz0LC4.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/sceneUboDeclaration-kGrRDglr.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-CgQTw0M7.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/textureProcessor.fragment-DnEEx4Gs.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/tgaTextureLoader-CwaQqeYn.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/assets/vertexColorMixing-C2cK_vck.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/favicon.svg +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/index.html +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/_viewer_static/sw.js +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/build-info.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/cli.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/context.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/determinism.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/drawings/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/drawings/_catalog.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/drawings/_validation.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/elements.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exceptions.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/base.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/__init__.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/annotations.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/dxf.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/model.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/pdf.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/primitives.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/projection.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/drawings/svg.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/glb.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/quantities.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/exporters/step.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/project_config.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/py.typed +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/recipes.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/runtime_sync.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/build-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/design-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/download-manifest-2.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/drawing-annotations-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/glb-manifest-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/ifc-validation-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/quantities-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/run-metadata-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/site-metadata-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/schemas/step-validation-1.json +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/site.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/.gitignore +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/README.md +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/config.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/drawing_annotations.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/generated/.gitkeep +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/model.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/templates/project/pyproject.toml +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools/units.py +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/SOURCES.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/dependency_links.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/entry_points.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/requires.txt +0 -0
- {python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/top_level.txt +0 -0
|
@@ -7,6 +7,30 @@ stable release is published.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.18] - 2026-10-08
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Curved B-rep solids (spheres, `cylinder_between` cylinders and other curved
|
|
15
|
+
shapes) no longer fail `build` and `verify` with `artifact_integrity:
|
|
16
|
+
IFC/design bounds mismatch`. The design manifest records each element's
|
|
17
|
+
`body_bounds_mm` (the bounds of the body IFC actually writes: the mesh of a
|
|
18
|
+
tessellated solid, the exact shape for recipes), and the IFC check compares
|
|
19
|
+
against it at the same `1e-6` tolerance. Manifests without the field fall
|
|
20
|
+
back to `bounds_mm`. `body_bounds_mm` describes the export, not the design,
|
|
21
|
+
so it is left out of `semantic_hash`: design hashes are unchanged, and
|
|
22
|
+
`validate` does not tessellate.
|
|
23
|
+
- `validate` reports a build123d `Part` (or compound) that holds one solid as
|
|
24
|
+
`solid-wrapped` with the fix (`.solid()`), instead of a bare
|
|
25
|
+
`solid-invalid`.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- A build tessellates each element once and shares the mesh between the
|
|
30
|
+
design manifest, IFC and GLB (`geometry.shared_tessellation`), instead of
|
|
31
|
+
IFC and GLB each meshing it. `benge-property-cad`'s full build went from
|
|
32
|
+
106 s to 67 s on the owner's Mac.
|
|
33
|
+
|
|
10
34
|
## [0.1.16] - 2026-09-22
|
|
11
35
|
|
|
12
36
|
### 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.18}/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
|
|
@@ -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"
|
|
@@ -153,9 +153,8 @@ def verify_output_root(output_root: Path, project_root: Path | None = None) -> V
|
|
|
153
153
|
_verify_sources(project_root, document)
|
|
154
154
|
selected = _selected_formats(document)
|
|
155
155
|
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):
|
|
156
|
+
recorded_design_hash = design.get("semantic_hash")
|
|
157
|
+
if recorded_design_hash != semantic_hash(design_semantic_projection(design)):
|
|
159
158
|
raise ArtifactIntegrityError("Design manifest semantic_hash does not reproduce")
|
|
160
159
|
if document["design_semantic_hash"] != design["semantic_hash"]:
|
|
161
160
|
raise ArtifactIntegrityError("Build and design manifest semantic hashes disagree")
|
|
@@ -386,7 +385,11 @@ def _reconcile_formats(root: Path, formats: tuple[str, ...]) -> None:
|
|
|
386
385
|
for item in elements
|
|
387
386
|
if item["physical"] and "ifc" in item["export_formats"] and item["ifc_class"] is not None
|
|
388
387
|
]
|
|
389
|
-
|
|
388
|
+
# Tessellated IFC bodies are meshes; compare them with the same mesh, recorded in the
|
|
389
|
+
# manifest as body_bounds_mm (0.1.18). Older manifests fall back to the exact bounds.
|
|
390
|
+
_require_matching_bounds(
|
|
391
|
+
"IFC", report["bounds_mm"], _combined_manifest_bounds(expected_elements, key="body_bounds_mm")
|
|
392
|
+
)
|
|
390
393
|
_reconcile_ifc_extensions(root, formats, report, expected_elements)
|
|
391
394
|
if "glb" in formats:
|
|
392
395
|
from .exporters.glb import glb_json
|
|
@@ -536,14 +539,15 @@ def _normalized_text(value: str) -> str:
|
|
|
536
539
|
return " ".join(value.split())
|
|
537
540
|
|
|
538
541
|
|
|
539
|
-
def _combined_manifest_bounds(elements: list[dict[str, Any]]) -> list[float]:
|
|
542
|
+
def _combined_manifest_bounds(elements: list[dict[str, Any]], key: str = "bounds_mm") -> list[float]:
|
|
540
543
|
if not elements:
|
|
541
544
|
return [0.0] * 6
|
|
545
|
+
values = [item.get(key) or item["bounds_mm"] for item in elements]
|
|
542
546
|
return [
|
|
543
|
-
round(min(float(
|
|
547
|
+
round(min(float(value[index]) for value in values), 6)
|
|
544
548
|
for index in range(3)
|
|
545
549
|
] + [
|
|
546
|
-
round(max(float(
|
|
550
|
+
round(max(float(value[index]) for value in values), 6)
|
|
547
551
|
for index in range(3, 6)
|
|
548
552
|
]
|
|
549
553
|
|
|
@@ -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
|
|
@@ -82,7 +83,7 @@ def build_project(options: BuildOptions) -> BuildResult:
|
|
|
82
83
|
raise TypeError("build_project expects BuildOptions")
|
|
83
84
|
requested = _validate_requested_formats(options.formats)
|
|
84
85
|
root = resolve_project_root(options.project_root)
|
|
85
|
-
with project_execution():
|
|
86
|
+
with project_execution(), shared_tessellation():
|
|
86
87
|
with project_lock(root):
|
|
87
88
|
config = load_project_config(root)
|
|
88
89
|
formats = config.default_formats if requested is None else requested
|
|
@@ -173,7 +174,7 @@ def validate_project(options: ValidationOptions) -> ValidationReport:
|
|
|
173
174
|
formats=formats,
|
|
174
175
|
issues=loaded.issues,
|
|
175
176
|
source_set_hash=source_set_hash,
|
|
176
|
-
design_semantic_hash=design_manifest(loaded.model)["semantic_hash"],
|
|
177
|
+
design_semantic_hash=design_manifest(loaded.model, include_body_bounds=False)["semantic_hash"],
|
|
177
178
|
annotation_provider_id=(
|
|
178
179
|
None if loaded.annotations is None else loaded.annotations.provider_id
|
|
179
180
|
),
|
|
@@ -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
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
from contextlib import contextmanager
|
|
7
|
+
from contextvars import ContextVar
|
|
5
8
|
from math import isfinite, sqrt
|
|
6
9
|
from typing import Any
|
|
7
10
|
|
|
@@ -51,20 +54,14 @@ def cylinder_between(
|
|
|
51
54
|
end: tuple[Length, Length, Length],
|
|
52
55
|
radius: Length,
|
|
53
56
|
) -> Solid:
|
|
54
|
-
"""Build a
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
``
|
|
60
|
-
|
|
61
|
-
``
|
|
62
|
-
must survive that check, author it with ``python_cad_tools.recipes``
|
|
63
|
-
(``CircleProfile`` + ``ExtrudedProfile``) instead, which exports exact
|
|
64
|
-
analytic IFC geometry and does not have this problem. Prefer
|
|
65
|
-
``cylinder_between`` only where an approximate B-rep solid is acceptable
|
|
66
|
-
(e.g. it is never exported to IFC, or exact bounds agreement is not
|
|
67
|
-
checked).
|
|
57
|
+
"""Build a B-rep cylinder between two points.
|
|
58
|
+
|
|
59
|
+
IFC exports it as a triangle mesh; the build's IFC bounds check compares
|
|
60
|
+
that mesh with the same tessellation recorded in the design manifest
|
|
61
|
+
(``body_bounds_mm``), so it builds and verifies like any other solid
|
|
62
|
+
(0.1.18; see ``docs/spikes/curved-geometry-ifc-bounds.md``). Where an
|
|
63
|
+
analytic IFC body is wanted instead of a mesh, author it with
|
|
64
|
+
``python_cad_tools.recipes`` (``CircleProfile`` + ``ExtrudedProfile``).
|
|
68
65
|
"""
|
|
69
66
|
_positive_lengths((radius,), "Cylinder radius")
|
|
70
67
|
start_mm = _point(start, "Cylinder start")
|
|
@@ -152,11 +149,80 @@ def combined_bounds(shapes: list[Any]) -> tuple[float, float, float, float, floa
|
|
|
152
149
|
)
|
|
153
150
|
|
|
154
151
|
|
|
152
|
+
#: The (linear, angular) deflection of every tessellated IFC body. The design manifest's
|
|
153
|
+
#: ``body_bounds_mm`` uses the same values, so the IFC bounds check compares the exported
|
|
154
|
+
#: mesh with that same mesh (2026-10-08 approval, curved-geometry-ifc-bounds).
|
|
155
|
+
IFC_TESSELLATION: tuple[float, float] = (0.5, 0.25)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
#: One build's tessellations, keyed by shape identity and deflections. The design manifest
|
|
159
|
+
#: (``body_bounds_mm``), IFC and GLB all mesh each element with the same deflections, so a
|
|
160
|
+
#: build meshes each shape once instead of up to three times. The value keeps the shape alive,
|
|
161
|
+
#: so its ``id`` cannot be reused while the cache exists. Results are shared: callers must not
|
|
162
|
+
#: mutate them.
|
|
163
|
+
_TESSELLATIONS: ContextVar[dict[tuple[int, float, float], tuple[Any, Any]] | None] = ContextVar(
|
|
164
|
+
"python_cad_tools_tessellations", default=None
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@contextmanager
|
|
169
|
+
def shared_tessellation() -> Iterator[None]:
|
|
170
|
+
"""Reuse each shape's tessellation for the duration of one build."""
|
|
171
|
+
token = _TESSELLATIONS.set({})
|
|
172
|
+
try:
|
|
173
|
+
yield
|
|
174
|
+
finally:
|
|
175
|
+
_TESSELLATIONS.reset(token)
|
|
176
|
+
|
|
177
|
+
|
|
155
178
|
def tessellate(shape: Any, linear_deflection: float, angular_deflection: float) -> tuple[list[list[float]], list[list[int]]]:
|
|
179
|
+
cache = _TESSELLATIONS.get()
|
|
180
|
+
key = (id(shape), float(linear_deflection), float(angular_deflection))
|
|
181
|
+
if cache is not None:
|
|
182
|
+
hit = cache.get(key)
|
|
183
|
+
if hit is not None and hit[0] is shape:
|
|
184
|
+
result: tuple[list[list[float]], list[list[int]]] = hit[1]
|
|
185
|
+
return result
|
|
156
186
|
vertices, triangles = shape.tessellate(linear_deflection, angular_deflection)
|
|
157
187
|
points = [[float(vertex.X), float(vertex.Y), float(vertex.Z)] for vertex in vertices]
|
|
158
188
|
faces = [[int(index) for index in triangle] for triangle in triangles]
|
|
159
|
-
|
|
189
|
+
computed = (points, faces)
|
|
190
|
+
if cache is not None:
|
|
191
|
+
cache[key] = (shape, computed)
|
|
192
|
+
return computed
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def mesh_bounds(
|
|
196
|
+
shape: Any, linear_deflection: float, angular_deflection: float
|
|
197
|
+
) -> tuple[float, float, float, float, float, float]:
|
|
198
|
+
"""Bounds of ``shape``'s tessellation: what a mesh export of it actually contains.
|
|
199
|
+
|
|
200
|
+
A curved surface's mesh lies inside the true surface, so these can be tighter than
|
|
201
|
+
:func:`bounds`; for a flat-faced solid they are equal.
|
|
202
|
+
"""
|
|
203
|
+
vertices, _ = tessellate(shape, linear_deflection, angular_deflection)
|
|
204
|
+
if not vertices:
|
|
205
|
+
return bounds(shape)
|
|
206
|
+
return (
|
|
207
|
+
min(vertex[0] for vertex in vertices),
|
|
208
|
+
min(vertex[1] for vertex in vertices),
|
|
209
|
+
min(vertex[2] for vertex in vertices),
|
|
210
|
+
max(vertex[0] for vertex in vertices),
|
|
211
|
+
max(vertex[1] for vertex in vertices),
|
|
212
|
+
max(vertex[2] for vertex in vertices),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def single_wrapped_solid(shape: Any) -> Solid | None:
|
|
217
|
+
"""The one valid solid inside a compound (such as build123d's algebra-mode ``Part``), or
|
|
218
|
+
``None`` when ``shape`` is not such a wrapper."""
|
|
219
|
+
if isinstance(shape, Solid) or not hasattr(shape, "solids"):
|
|
220
|
+
return None
|
|
221
|
+
try:
|
|
222
|
+
solids = list(shape.solids())
|
|
223
|
+
except Exception: # noqa: BLE001 -- any shape that cannot list solids is not a wrapper
|
|
224
|
+
return None
|
|
225
|
+
return solids[0] if len(solids) == 1 and is_valid_solid(solids[0]) else None
|
|
160
226
|
|
|
161
227
|
|
|
162
228
|
def is_valid_solid(shape: Any) -> bool:
|
|
@@ -13,7 +13,7 @@ from typing import Any
|
|
|
13
13
|
from . import __version__
|
|
14
14
|
from .determinism import normalized_epoch_iso, semantic_hash, write_json
|
|
15
15
|
from .exceptions import ArtifactIntegrityError
|
|
16
|
-
from .geometry import bounds
|
|
16
|
+
from .geometry import IFC_TESSELLATION, bounds, mesh_bounds
|
|
17
17
|
from .recipes import DifferenceRecipe, ExtrudedProfile
|
|
18
18
|
|
|
19
19
|
SCHEMAS: dict[str, tuple[int, frozenset[str]]] = {
|
|
@@ -68,7 +68,37 @@ _SNAKE_CASE = re.compile(r"[a-z][a-z0-9]*(?:_[a-z0-9]+)*\Z")
|
|
|
68
68
|
_DRAWING_ID = re.compile(r"[A-Za-z0-9._-]+\Z", re.ASCII)
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def _body_bounds(element: Any) -> tuple[float, float, float, float, float, float]:
|
|
72
|
+
"""Bounds of the body the IFC exporter writes: the mesh of a tessellated solid, the exact
|
|
73
|
+
shape otherwise (recipes are exported analytically; non-solids are not meshed)."""
|
|
74
|
+
if element.recipe is None and element.geometry_kind == "solid":
|
|
75
|
+
return mesh_bounds(element.geometry, *IFC_TESSELLATION)
|
|
76
|
+
return bounds(element.geometry)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#: Per-element manifest keys that describe an export (not the design) and so are left out of
|
|
80
|
+
#: ``semantic_hash``: a project's design hash is the same with or without them, and
|
|
81
|
+
#: ``validate`` (which reports the hash) need not tessellate every element.
|
|
82
|
+
_EXPORT_ONLY_ELEMENT_KEYS = frozenset({"body_bounds_mm"})
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def design_semantic_projection(manifest: dict[str, Any]) -> dict[str, Any]:
|
|
86
|
+
"""The design manifest as hashed: without ``semantic_hash`` and export-only element keys."""
|
|
87
|
+
projected = {key: value for key, value in manifest.items() if key != "semantic_hash"}
|
|
88
|
+
elements = projected.get("elements")
|
|
89
|
+
if isinstance(elements, list):
|
|
90
|
+
projected["elements"] = [
|
|
91
|
+
{key: value for key, value in item.items() if key not in _EXPORT_ONLY_ELEMENT_KEYS}
|
|
92
|
+
if isinstance(item, dict)
|
|
93
|
+
else item
|
|
94
|
+
for item in elements
|
|
95
|
+
]
|
|
96
|
+
return projected
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def design_manifest(model: Any, *, include_body_bounds: bool = True) -> dict[str, Any]:
|
|
100
|
+
"""The design manifest. ``include_body_bounds=False`` skips ``body_bounds_mm`` (and its
|
|
101
|
+
tessellation) when only the semantic hash is needed; the hash is the same either way."""
|
|
72
102
|
elements = []
|
|
73
103
|
for element in model.walk():
|
|
74
104
|
elements.append(
|
|
@@ -79,6 +109,11 @@ def design_manifest(model: Any) -> dict[str, Any]:
|
|
|
79
109
|
"geometry_kind": element.geometry_kind,
|
|
80
110
|
"physical": element.physical,
|
|
81
111
|
"bounds_mm": [round(value, 6) for value in bounds(element.geometry)],
|
|
112
|
+
**(
|
|
113
|
+
{"body_bounds_mm": [round(value, 6) for value in _body_bounds(element)]}
|
|
114
|
+
if include_body_bounds
|
|
115
|
+
else {}
|
|
116
|
+
),
|
|
82
117
|
"placement": {
|
|
83
118
|
"translation_mm": element.placement.translation_mm,
|
|
84
119
|
"rotation_deg_xyz": element.placement.rotation_deg_xyz,
|
|
@@ -119,7 +154,7 @@ def design_manifest(model: Any) -> dict[str, Any]:
|
|
|
119
154
|
"glb": {"site_path": f"artifacts/glb/{model.artifact_stem}.glb"},
|
|
120
155
|
"elements": elements,
|
|
121
156
|
}
|
|
122
|
-
value["semantic_hash"] = semantic_hash(value)
|
|
157
|
+
value["semantic_hash"] = semantic_hash(design_semantic_projection(value))
|
|
123
158
|
return value
|
|
124
159
|
|
|
125
160
|
|
|
@@ -15,7 +15,7 @@ from build123d import (
|
|
|
15
15
|
|
|
16
16
|
from .elements import DesignElement, DesignModel, MaterialSpec, Opening, Placement
|
|
17
17
|
from .exceptions import ModelValidationError
|
|
18
|
-
from .geometry import bounds, is_valid_solid
|
|
18
|
+
from .geometry import bounds, is_valid_solid, single_wrapped_solid
|
|
19
19
|
from .recipes import (
|
|
20
20
|
ROTATION_X_RANGE,
|
|
21
21
|
ROTATION_Y_RANGE,
|
|
@@ -108,9 +108,21 @@ def _validate_element(
|
|
|
108
108
|
if element.physical and element.geometry_kind != "solid":
|
|
109
109
|
issues.append(ValidationIssue("physical-kind", "error", "Physical elements must be solids", element_id=element.id))
|
|
110
110
|
if element.physical and element.geometry is not None and not is_valid_solid(element.geometry):
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
if single_wrapped_solid(element.geometry) is not None:
|
|
112
|
+
issues.append(
|
|
113
|
+
ValidationIssue(
|
|
114
|
+
"solid-wrapped",
|
|
115
|
+
"error",
|
|
116
|
+
"Geometry is a Part/Compound containing one solid; pass `.solid()` (the single Solid) instead",
|
|
117
|
+
element_id=element.id,
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
issues.append(
|
|
122
|
+
ValidationIssue(
|
|
123
|
+
"solid-invalid", "error", "Physical geometry must be a valid positive-volume solid", element_id=element.id
|
|
124
|
+
)
|
|
125
|
+
)
|
|
114
126
|
if not element.physical and element.geometry_kind == "solid":
|
|
115
127
|
issues.append(
|
|
116
128
|
ValidationIssue(
|
{python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/src/python_cad_tools.egg-info/scm_file_list.json
RENAMED
|
@@ -263,6 +263,7 @@
|
|
|
263
263
|
"src/python_cad_tools/validation.py",
|
|
264
264
|
"tests/conftest.py",
|
|
265
265
|
"tests/integration/test_build_transactions.py",
|
|
266
|
+
"tests/integration/test_curved_geometry.py",
|
|
266
267
|
"tests/integration/test_drawing_extensions.py",
|
|
267
268
|
"tests/integration/test_exports.py",
|
|
268
269
|
"tests/integration/test_project_loading.py",
|
|
@@ -271,6 +272,7 @@
|
|
|
271
272
|
"tests/packaging/test_toolchain.py",
|
|
272
273
|
"tests/typing/public_project.py",
|
|
273
274
|
"tests/typing/test_external_typing.py",
|
|
275
|
+
"tests/unit/test_curved_geometry_units.py",
|
|
274
276
|
"tests/unit/test_drawings.py",
|
|
275
277
|
"tests/unit/test_manifests.py",
|
|
276
278
|
"tests/unit/test_model_contract.py",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_cad_tools-0.1.17 → python_cad_tools-0.1.18}/.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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|