diff --git a/content/kcl-test-outputs/models/serial_test_example_fn_std-solver-angleDimension0_output.gltf b/content/kcl-test-outputs/models/serial_test_example_fn_std-solver-angleDimension0_output.gltf new file mode 100644 index 00000000..ca086df7 --- /dev/null +++ b/content/kcl-test-outputs/models/serial_test_example_fn_std-solver-angleDimension0_output.gltf @@ -0,0 +1,1632 @@ +{ + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.0019999800715595484, + 0, + -0.003464010078459978 + ], + "max": [ + 0.004000000189989805, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 0, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.00000000999999993922529, + 0, + -0.003464010078459978 + ], + "max": [ + 0.0019999800715595484, + 0.0020000000949949026, + -0.00000000999999993922529 + ] + }, + { + "bufferView": 1, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.00000000999999993922529, + 0, + -0.00000000999999993922529 + ], + "max": [ + 0.004000000189989805, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 2, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 0, + "count": 3, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.00000000999999993922529, + 0, + -0.003464010078459978 + ], + "max": [ + 0.004000000189989805, + 0, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 3, + "byteOffset": 12, + "count": 3, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 4, + "byteOffset": 0, + "count": 3, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.00000000999999993922529, + 0.0020000000949949026, + -0.003464010078459978 + ], + "max": [ + 0.004000000189989805, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 4, + "byteOffset": 12, + "count": 3, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 5, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.008999980054795742, + 0, + -0.003464010078459978 + ], + "max": [ + 0.010999999940395355, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 5, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 6, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.007000009994953871, + 0, + -0.003464010078459978 + ], + "max": [ + 0.008999980054795742, + 0.0020000000949949026, + -0.00000000999999993922529 + ] + }, + { + "bufferView": 6, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 7, + "byteOffset": 0, + "count": 6, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.007000009994953871, + 0, + -0.00000000999999993922529 + ], + "max": [ + 0.010999999940395355, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 7, + "byteOffset": 12, + "count": 6, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 8, + "byteOffset": 0, + "count": 3, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.007000009994953871, + 0, + -0.003464010078459978 + ], + "max": [ + 0.010999999940395355, + 0, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 8, + "byteOffset": 12, + "count": 3, + "componentType": 5126, + "type": "VEC3" + }, + { + "bufferView": 9, + "byteOffset": 0, + "count": 3, + "componentType": 5126, + "type": "VEC3", + "min": [ + 0.007000009994953871, + 0.0020000000949949026, + -0.003464010078459978 + ], + "max": [ + 0.010999999940395355, + 0.0020000000949949026, + 0.00000001999999987845058 + ] + }, + { + "bufferView": 9, + "byteOffset": 12, + "count": 3, + "componentType": 5126, + "type": "VEC3" + } + ], + "asset": { + "generator": "zoo.dev", + "version": "2.0" + }, + "buffers": [ + { + "byteLength": 1152, + "uri": "data:application/octet-stream;base64,bxKDO28SAzt3zKsybbNdPwAAAAC5AAC/bxKDOwAAAAB3zKsybbNdPwAAAAC5AAC/GRIDO28SAztyBGO7bbNdPwAAAAC5AAC/GRIDO28SAztyBGO7bbNdPwAAAAC5AAC/bxKDOwAAAAB3zKsybbNdPwAAAAC5AAC/GRIDOwAAAAByBGO7bbNdPwAAAAC5AAC/GRIDO28SAztyBGO7orNdvwAAAABcAAC/GRIDOwAAAAByBGO7orNdvwAAAABcAAC/d8wrMm8SAzt3zCuyorNdvwAAAABcAAC/d8wrMm8SAzt3zCuyorNdvwAAAABcAAC/GRIDOwAAAAByBGO7orNdvwAAAABcAAC/d8wrMgAAAAB3zCuyorNdvwAAAABcAAC/d8wrMm8SAzt3zCuyFhLVtgAAAAAAAIA/d8wrMgAAAAB3zCuyFhLVtgAAAAAAAIA/bxKDO28SAzt3zKsyFhLVtgAAAAAAAIA/bxKDO28SAzt3zKsyFhLVtgAAAAAAAIA/d8wrMgAAAAB3zCuyFhLVtgAAAAAAAIA/bxKDOwAAAAB3zKsyFhLVtgAAAAAAAIA/d8wrMgAAAAB3zCuyAAAAgAAAgL8AAACAGRIDOwAAAAByBGO7AAAAgAAAgL8AAACAbxKDOwAAAAB3zKsyAAAAgAAAgL8AAACAd8wrMm8SAzt3zCuyAAAAAAAAgD8AAAAAbxKDO28SAzt3zKsyAAAAAAAAgD8AAAAAGRIDO28SAztyBGO7AAAAAAAAgD8AAAAAWDk0PG8SAzt3zKsybbNdPwAAAAC5AAC/WDk0PAAAAAB3zKsybbNdPwAAAAC5AAC/p3QTPG8SAztyBGO7bbNdPwAAAAC5AAC/p3QTPG8SAztyBGO7bbNdPwAAAAC5AAC/WDk0PAAAAAB3zKsybbNdPwAAAAC5AAC/p3QTPAAAAAByBGO7bbNdPwAAAAC5AAC/p3QTPG8SAztyBGO7orNdvwAAAABcAAC/p3QTPAAAAAByBGO7orNdvwAAAABcAAC/V2DlO28SAzt3zCuyorNdvwAAAABcAAC/V2DlO28SAzt3zCuyorNdvwAAAABcAAC/p3QTPAAAAAByBGO7orNdvwAAAABcAAC/V2DlOwAAAAB3zCuyorNdvwAAAABcAAC/V2DlO28SAzt3zCuyFhLVtgAAAAAAAIA/V2DlOwAAAAB3zCuyFhLVtgAAAAAAAIA/WDk0PG8SAzt3zKsyFhLVtgAAAAAAAIA/WDk0PG8SAzt3zKsyFhLVtgAAAAAAAIA/V2DlOwAAAAB3zCuyFhLVtgAAAAAAAIA/WDk0PAAAAAB3zKsyFhLVtgAAAAAAAIA/V2DlOwAAAAB3zCuyAAAAgAAAgL8AAACAp3QTPAAAAAByBGO7AAAAgAAAgL8AAACAWDk0PAAAAAB3zKsyAAAAgAAAgL8AAACAV2DlO28SAzt3zCuyAAAAAAAAgD8AAAAAWDk0PG8SAzt3zKsyAAAAAAAAgD8AAAAAp3QTPG8SAztyBGO7AAAAAAAAgD8AAAAA" + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 0, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 144, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 288, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 72, + "byteOffset": 432, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 72, + "byteOffset": 504, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 576, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 720, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 144, + "byteOffset": 864, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 72, + "byteOffset": 1008, + "byteStride": 24, + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 72, + "byteOffset": 1080, + "byteStride": 24, + "target": 34962 + } + ], + "scene": 0, + "extensions": { + "KITTYCAD_boundary_representation": { + "solids": [ + { + "shells": [ + [ + 0, + 1 + ] + ], + "mesh": 0, + "extras": { + "KITTYCAD": { + "material": 0 + } + } + }, + { + "shells": [ + [ + 1, + 1 + ] + ], + "mesh": 1, + "extras": { + "KITTYCAD": { + "material": 1 + } + } + } + ], + "shells": [ + { + "faces": [ + [ + 0, + 1 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ], + [ + 3, + 1 + ], + [ + 4, + 1 + ] + ] + }, + { + "faces": [ + [ + 5, + 1 + ], + [ + 6, + 1 + ], + [ + 7, + 1 + ], + [ + 8, + 1 + ], + [ + 9, + 1 + ] + ] + } + ], + "faces": [ + { + "surface": [ + 0, + 1 + ], + "loops": [ + [ + 0, + 1 + ] + ] + }, + { + "surface": [ + 1, + 1 + ], + "loops": [ + [ + 1, + 1 + ] + ] + }, + { + "surface": [ + 2, + 1 + ], + "loops": [ + [ + 2, + 1 + ] + ] + }, + { + "surface": [ + 3, + -1 + ], + "loops": [ + [ + 3, + 1 + ] + ] + }, + { + "surface": [ + 4, + 1 + ], + "loops": [ + [ + 4, + 1 + ] + ] + }, + { + "surface": [ + 5, + 1 + ], + "loops": [ + [ + 5, + 1 + ] + ] + }, + { + "surface": [ + 6, + 1 + ], + "loops": [ + [ + 6, + 1 + ] + ] + }, + { + "surface": [ + 7, + 1 + ], + "loops": [ + [ + 7, + 1 + ] + ] + }, + { + "surface": [ + 8, + -1 + ], + "loops": [ + [ + 8, + 1 + ] + ] + }, + { + "surface": [ + 9, + 1 + ], + "loops": [ + [ + 9, + 1 + ] + ] + } + ], + "loops": [ + { + "edges": [ + [ + 0, + 1 + ], + [ + 1, + 1 + ], + [ + 2, + -1 + ], + [ + 3, + -1 + ] + ] + }, + { + "edges": [ + [ + 4, + 1 + ], + [ + 5, + 1 + ], + [ + 6, + -1 + ], + [ + 1, + -1 + ] + ] + }, + { + "edges": [ + [ + 7, + 1 + ], + [ + 3, + 1 + ], + [ + 8, + -1 + ], + [ + 5, + -1 + ] + ] + }, + { + "edges": [ + [ + 7, + -1 + ], + [ + 4, + -1 + ], + [ + 0, + -1 + ] + ] + }, + { + "edges": [ + [ + 2, + 1 + ], + [ + 6, + 1 + ], + [ + 8, + 1 + ] + ] + }, + { + "edges": [ + [ + 9, + 1 + ], + [ + 10, + 1 + ], + [ + 11, + -1 + ], + [ + 12, + -1 + ] + ] + }, + { + "edges": [ + [ + 13, + 1 + ], + [ + 14, + 1 + ], + [ + 15, + -1 + ], + [ + 10, + -1 + ] + ] + }, + { + "edges": [ + [ + 16, + 1 + ], + [ + 12, + 1 + ], + [ + 17, + -1 + ], + [ + 14, + -1 + ] + ] + }, + { + "edges": [ + [ + 16, + -1 + ], + [ + 13, + -1 + ], + [ + 9, + -1 + ] + ] + }, + { + "edges": [ + [ + 11, + 1 + ], + [ + 15, + 1 + ], + [ + 17, + 1 + ] + ] + } + ], + "edges": [ + { + "curve": [ + 0, + 1 + ], + "start": 0, + "end": 1, + "t": [ + 0, + 0.003999947979824238 + ] + }, + { + "curve": [ + 1, + 1 + ], + "start": 1, + "end": 2, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 2, + 1 + ], + "start": 3, + "end": 2, + "t": [ + 0, + 0.003999947979824238 + ] + }, + { + "curve": [ + 3, + 1 + ], + "start": 0, + "end": 3, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 4, + 1 + ], + "start": 1, + "end": 4, + "t": [ + 0, + 0.003999896998786344 + ] + }, + { + "curve": [ + 5, + 1 + ], + "start": 4, + "end": 5, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 6, + 1 + ], + "start": 2, + "end": 5, + "t": [ + 0, + 0.003999896998786344 + ] + }, + { + "curve": [ + 7, + 1 + ], + "start": 4, + "end": 0, + "t": [ + 0, + 0.0039999900001124996 + ] + }, + { + "curve": [ + 8, + 1 + ], + "start": 5, + "end": 3, + "t": [ + 0, + 0.0039999900001124996 + ] + }, + { + "curve": [ + 9, + 1 + ], + "start": 6, + "end": 7, + "t": [ + 0, + 0.003999947979824238 + ] + }, + { + "curve": [ + 10, + 1 + ], + "start": 7, + "end": 8, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 11, + 1 + ], + "start": 9, + "end": 8, + "t": [ + 0, + 0.003999947979824238 + ] + }, + { + "curve": [ + 12, + 1 + ], + "start": 6, + "end": 9, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 13, + 1 + ], + "start": 7, + "end": 10, + "t": [ + 0, + 0.003999896998786343 + ] + }, + { + "curve": [ + 14, + 1 + ], + "start": 10, + "end": 11, + "t": [ + 0, + 0.002 + ] + }, + { + "curve": [ + 15, + 1 + ], + "start": 8, + "end": 11, + "t": [ + 0, + 0.003999896998786343 + ] + }, + { + "curve": [ + 16, + 1 + ], + "start": 10, + "end": 6, + "t": [ + 0, + 0.003999990000112499 + ] + }, + { + "curve": [ + 17, + 1 + ], + "start": 11, + "end": 9, + "t": [ + 0, + 0.003999990000112499 + ] + } + ], + "vertices": [ + [ + 0.004, + 0, + 0.00000002 + ], + [ + 0.00199998, + 0, + -0.00346401 + ], + [ + 0.00199998, + 0.002, + -0.00346401 + ], + [ + 0.004, + 0.002, + 0.00000002 + ], + [ + 0.00000001, + 0, + -0.00000001 + ], + [ + 0.00000001, + 0.002, + -0.00000001 + ], + [ + 0.011, + 0, + 0.00000002 + ], + [ + 0.00899998, + 0, + -0.00346401 + ], + [ + 0.00899998, + 0.002, + -0.00346401 + ], + [ + 0.011, + 0.002, + 0.00000002 + ], + [ + 0.00700001, + 0, + -0.00000001 + ], + [ + 0.00700001, + 0.002, + -0.00000001 + ] + ], + "surfaces": [ + { + "type": "plane", + "plane": { + "xAxis": [ + 0.5000110012290514, + 0, + 0.8660190521287171 + ], + "yAxis": [ + 0, + -1, + 0 + ], + "origin": [ + 0.00299999, + 0.001, + -0.001732 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 0.5000054992788864, + 0, + -0.8660222287510129 + ], + "yAxis": [ + 0, + -1, + -0 + ], + "origin": [ + 0.001, + 0.001, + -0.00173201 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 0.9999999999798388, + 0, + 0.000006349999999871976 + ], + "yAxis": [ + 0, + 1, + -0 + ], + "origin": [ + 0.00200001, + 0.001, + 0.00000001 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 1, + 0, + 0 + ], + "yAxis": [ + 0, + 0, + -1 + ], + "origin": [ + 0, + 0, + -0 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 1, + 0, + 0 + ], + "yAxis": [ + 0, + 0, + -1 + ], + "origin": [ + 0, + 0.002, + -0 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 0.5000110012290514, + 0, + 0.8660190521287171 + ], + "yAxis": [ + 0, + -1, + 0 + ], + "origin": [ + 0.00999999, + 0.001, + -0.001732 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 0.5000054992788864, + 0, + -0.8660222287510129 + ], + "yAxis": [ + 0, + -1, + -0 + ], + "origin": [ + 0.008, + 0.001, + -0.00173201 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 0.9999999999798388, + 0, + 0.000006349999999871976 + ], + "yAxis": [ + 0, + 1, + -0 + ], + "origin": [ + 0.00900001, + 0.001, + 0.00000001 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 1, + 0, + 0 + ], + "yAxis": [ + 0, + 0, + -1 + ], + "origin": [ + 0, + 0, + -0 + ] + } + }, + { + "type": "plane", + "plane": { + "xAxis": [ + 1, + 0, + 0 + ], + "yAxis": [ + 0, + 0, + -1 + ], + "origin": [ + 0, + 0.002, + -0 + ] + } + } + ], + "curves3D": [ + { + "type": "line", + "line": { + "origin": [ + 0.004, + 0, + 0.00000002 + ], + "direction": [ + -0.500011502671563, + 0, + -0.8660187626120611 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00199998, + 0, + -0.00346401 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.004, + 0.002, + 0.00000002 + ], + "direction": [ + -0.500011502671563, + 0, + -0.8660187626120611 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.004, + 0, + 0.00000002 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00199998, + 0, + -0.00346401 + ], + "direction": [ + -0.5000053752901225, + 0, + 0.866022300336997 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00000001, + 0, + -0.00000001 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00199998, + 0.002, + -0.00346401 + ], + "direction": [ + -0.5000053752901225, + 0, + 0.866022300336997 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00000001, + 0, + -0.00000001 + ], + "direction": [ + 0.9999999999718748, + 0, + 0.000007500018749835938 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00000001, + 0.002, + -0.00000001 + ], + "direction": [ + 0.9999999999718748, + 0, + 0.000007500018749835938 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.011, + 0, + 0.00000002 + ], + "direction": [ + -0.500011502671563, + 0, + -0.8660187626120611 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00899998, + 0, + -0.00346401 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.011, + 0.002, + 0.00000002 + ], + "direction": [ + -0.500011502671563, + 0, + -0.8660187626120611 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.011, + 0, + 0.00000002 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00899998, + 0, + -0.00346401 + ], + "direction": [ + -0.5000053752901223, + 0, + 0.8660223003369971 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00700001, + 0, + -0.00000001 + ], + "direction": [ + 0, + 1, + 0 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00899998, + 0.002, + -0.00346401 + ], + "direction": [ + -0.5000053752901223, + 0, + 0.8660223003369971 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00700001, + 0, + -0.00000001 + ], + "direction": [ + 0.9999999999718748, + 0, + 0.000007500018749835939 + ] + } + }, + { + "type": "line", + "line": { + "origin": [ + 0.00700001, + 0.002, + -0.00000001 + ], + "direction": [ + 0.9999999999718748, + 0, + 0.000007500018749835939 + ] + } + } + ] + } + }, + "extensionsUsed": [ + "KITTYCAD_boundary_representation" + ], + "materials": [ + { + "alphaMode": "OPAQUE", + "doubleSided": false, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.9, + 0.9, + 0.9, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "emissiveFactor": [ + 0, + 0, + 0 + ] + }, + { + "alphaMode": "OPAQUE", + "doubleSided": false, + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.9, + 0.9, + 0.9, + 1 + ], + "metallicFactor": 1, + "roughnessFactor": 1 + }, + "emissiveFactor": [ + 0, + 0, + 0 + ] + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "POSITION": 0, + "NORMAL": 1 + }, + "material": 0 + }, + { + "attributes": { + "POSITION": 2, + "NORMAL": 3 + }, + "material": 0 + }, + { + "attributes": { + "POSITION": 4, + "NORMAL": 5 + }, + "material": 0 + }, + { + "attributes": { + "POSITION": 6, + "NORMAL": 7 + }, + "material": 0 + }, + { + "attributes": { + "POSITION": 8, + "NORMAL": 9 + }, + "material": 0 + } + ] + }, + { + "primitives": [ + { + "attributes": { + "POSITION": 10, + "NORMAL": 11 + }, + "material": 1 + }, + { + "attributes": { + "POSITION": 12, + "NORMAL": 13 + }, + "material": 1 + }, + { + "attributes": { + "POSITION": 14, + "NORMAL": 15 + }, + "material": 1 + }, + { + "attributes": { + "POSITION": 16, + "NORMAL": 17 + }, + "material": 1 + }, + { + "attributes": { + "POSITION": 18, + "NORMAL": 19 + }, + "material": 1 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ] + }, + { + "children": [ + 2, + 3 + ] + }, + { + "extensions": { + "KITTYCAD_boundary_representation": { + "solid": 0 + } + }, + "mesh": 0 + }, + { + "extensions": { + "KITTYCAD_boundary_representation": { + "solid": 1 + } + }, + "mesh": 1 + } + ], + "scenes": [ + { + "nodes": [ + 0 + ] + } + ] +} \ No newline at end of file diff --git a/content/kcl-test-outputs/serial_test_example_fn_std-solver-angleDimension0.png b/content/kcl-test-outputs/serial_test_example_fn_std-solver-angleDimension0.png new file mode 100644 index 00000000..255908b2 Binary files /dev/null and b/content/kcl-test-outputs/serial_test_example_fn_std-solver-angleDimension0.png differ diff --git a/content/pages/docs/kcl-lang/functions.md b/content/pages/docs/kcl-lang/functions.md index d939573c..7b77ec0a 100644 --- a/content/pages/docs/kcl-lang/functions.md +++ b/content/pages/docs/kcl-lang/functions.md @@ -44,6 +44,20 @@ two = increment(1) three = add(1, delta = 2) ``` +## Point-and-click editability + +Custom functions are useful when the same parameterized feature needs to be +reused with different inputs. However, Zoo Design Studio's point-and-click +tools cannot currently edit sketches inside a custom function body. + +Keep sketches at the top level when point-and-click editing is important. Use a +custom function when reuse is more important than point-and-click access to its +internal sketches. Repeating an identical body usually does not require a +custom function; use [`clone`](/docs/kcl-std/functions/std-clone), +[`patternLinear3d`](/docs/kcl-std/functions/std-solid-patternLinear3d), or +[`patternCircular3d`](/docs/kcl-std/functions/std-solid-patternCircular3d) +instead. + Below shows how a custom function must be called if it has a labeled argument, and another example with an unlabeled argument: ``` diff --git a/content/pages/docs/kcl-lang/index.md b/content/pages/docs/kcl-lang/index.md index 4df831cc..b5ed2c02 100644 --- a/content/pages/docs/kcl-lang/index.md +++ b/content/pages/docs/kcl-lang/index.md @@ -13,6 +13,7 @@ things in a more tutorial fashion. See also our documentation of the [standard l * [Arithmetic and logic](/docs/kcl-lang/arithmetic) * [Values and types](/docs/kcl-lang/types) * [Numeric types and units](/docs/kcl-lang/numeric) +* [Sketch blocks and constraints](/docs/kcl-lang/sketches) * [Functions](/docs/kcl-lang/functions) * [Arrays and ranges](/docs/kcl-lang/arrays) * [Enums](/docs/kcl-lang/enums) diff --git a/content/pages/docs/kcl-lang/sketches.md b/content/pages/docs/kcl-lang/sketches.md new file mode 100644 index 00000000..d94d0249 --- /dev/null +++ b/content/pages/docs/kcl-lang/sketches.md @@ -0,0 +1,125 @@ +--- +title: "Sketch Blocks and Constraints" +excerpt: "Write constrained, editable sketches with KCL sketch blocks." +layout: manual +--- + +KCL sketch blocks define 2D geometry and the relationships that control it. +Start a block on a base plane or supported face, add sketch geometry inside the +braces, then apply constraints to express design intent. + +```kcl +width = 40mm +height = 24mm + +profile = sketch(on = XY) { + bottom = line(start = [var 0mm, var 0mm], end = [var 40mm, var 0mm]) + right = line(start = [var 40mm, var 0mm], end = [var 40mm, var 24mm]) + top = line(start = [var 40mm, var 24mm], end = [var 0mm, var 24mm]) + left = line(start = [var 0mm, var 24mm], end = [var 0mm, var 0mm]) + + coincident([bottom.end, right.start]) + coincident([right.end, top.start]) + coincident([top.end, left.start]) + coincident([left.end, bottom.start]) + horizontal(bottom) + horizontal(top) + vertical(right) + vertical(left) + horizontalDistance([bottom.start, bottom.end]) == width + verticalDistance([bottom.start, left.start]) == height + coincident([bottom.start, ORIGIN]) +} +``` + +Inside a sketch block, the [solver module](/docs/kcl-std/modules/std-solver) +is automatically in scope. Call `line`, `arc`, `circle`, `coincident`, and +other solver functions without a `solver::` prefix. + +## `var` values are initial guesses + +A value introduced with `var` is a coordinate or size that the solver may +change. It is an initial guess, not a fixed dimension. Initial guesses must be +numeric literals, with a unit where applicable: + +```kcl +exampleSketch = sketch(on = XY) { + // Valid initial guesses + samplePoint = point(at = [var 0mm, var -3mm]) + coincident([samplePoint, [0mm, -3mm]]) + + // Invalid: identifiers and expressions cannot follow `var` + // samplePoint = point(at = [var width, var (height / 2)]) +} +``` + +Put identifiers and expressions in constraints when they must drive the solved +result. For example, use `horizontalDistance([edge.start, edge.end]) == width` +rather than `end = [var width, var 0mm]`. + +## Fully constrain the sketch + +A fully constrained sketch has no unintended degrees of freedom. Use geometric +constraints such as `coincident`, `horizontal`, `vertical`, `parallel`, +`perpendicular`, `equalLength`, `tangent`, and `symmetric` to describe +relationships. Use dimensional constraints such as `distance`, +`horizontalDistance`, `verticalDistance`, `angle`, `radius`, and `diameter` for +driving values. + +Anchor the profile once, then constrain the rest of the geometry relative to +that frame. Repeatedly fixing absolute points makes sketches harder to edit and +can over-constrain them. An under-constrained sketch can move in unintended +ways; an over-constrained sketch contains redundant or conflicting +relationships. + +See the [constraint reference](/docs/kcl-std/modules/std-solver) for the full +API and the [sketching guide](/docs/zoo-design-studio/features/3d-design/parametric-modeling/sketching) +for the point-and-click workflow. + +## Create a region from a closed profile + +Most solid features consume a [region](/docs/kcl-std/functions/std-sketch-region) +created from a closed sketch boundary. + +For one closed segment, such as a circle, pass that segment by itself. Omit +`intersectionIndex` and `direction`; they are unnecessary for one loop and are +intended to disambiguate a boundary traced from multiple segments. + +```kcl +roundProfile = sketch(on = XY) { + perimeter = circle(start = [var 10mm, var 0mm], center = [var 0mm, var 0mm]) + coincident([perimeter.center, ORIGIN]) + radius(perimeter) == 10mm + horizontal([perimeter.center, perimeter.start]) +} + +roundRegion = region(segments = [roundProfile.perimeter]) +roundBody = extrude(roundRegion, length = 5mm) +``` + +For a boundary traced from multiple intersecting segments, pass the first two +segments. Use `intersectionIndex` only when they intersect more than once, and +use `direction = CW` when the default counterclockwise trace selects the wrong +boundary. + +If segment tracing cannot identify the intended boundary, use a point strictly +inside the region and provide its sketch: + +```kcl +fallbackProfile = sketch(on = XY) { + perimeter = circle(start = [var 10mm, var 0mm], center = [var 0mm, var 0mm]) + coincident([perimeter.center, ORIGIN]) + radius(perimeter) == 10mm + horizontal([perimeter.center, perimeter.start]) +} + +fallbackRegion = region(point = [0mm, 0mm], sketch = fallbackProfile) +fallbackBody = extrude(fallbackRegion, length = 5mm) +``` + +## Control arc direction + +An [arc](/docs/kcl-std/functions/std-solver-arc) sweeps counterclockwise from +its start point to its end point by default. If it takes the long or opposite +path, set `direction = CW`. Changing the direction is clearer than swapping +endpoints and then repairing every dependent constraint. diff --git a/content/pages/docs/kcl-samples/angle-gauge/main.kcl b/content/pages/docs/kcl-samples/angle-gauge/main.kcl index e00195ea..fab1f729 100644 --- a/content/pages/docs/kcl-samples/angle-gauge/main.kcl +++ b/content/pages/docs/kcl-samples/angle-gauge/main.kcl @@ -88,10 +88,13 @@ gaugeProfileSketch = sketch(on = XY) { horizontal(cutoutTopEdge) horizontal(cutoutAngleReferenceEdge) vertical(cutoutLeftVerticalEdge) - angle([ - cutoutAngleReferenceEdge, - cutoutAngledEdge -]) == cutoutAngle + angleDimension( + lines = [ + cutoutAngleReferenceEdge, + cutoutAngledEdge + ], + sector = 1, +) == cutoutAngle horizontalDistance([cutoutTopEdge.start, cutoutTopEdge.end]) == cutoutDepth verticalDistance([ diff --git a/content/pages/docs/kcl-samples/artificial-heart/housing.kcl b/content/pages/docs/kcl-samples/artificial-heart/housing.kcl index fdfacc3b..c0cd14b6 100644 --- a/content/pages/docs/kcl-samples/artificial-heart/housing.kcl +++ b/content/pages/docs/kcl-samples/artificial-heart/housing.kcl @@ -213,7 +213,7 @@ sketch007 = sketch(on = XY) { line2 = line(start = [var 0.48in, var 0.75in], end = [var 0.53in, var 1.23in], construction = true) coincident([line2.start, arc1.center]) coincident([line2.end, arc2.start]) - angle([line2, line1]) == 6 + angleDimension(lines = [line2, line1], sector = 1, labelPosition = [0.28in, 1.38in]) == 6 } // Model the profile of the rear inlet bung, then sweep diff --git a/content/pages/docs/kcl-samples/artificial-heart/impeller.kcl b/content/pages/docs/kcl-samples/artificial-heart/impeller.kcl index a277b62b..ed82fe47 100644 --- a/content/pages/docs/kcl-samples/artificial-heart/impeller.kcl +++ b/content/pages/docs/kcl-samples/artificial-heart/impeller.kcl @@ -105,7 +105,7 @@ sketch003 = sketch(on = offsetPlane(XZ, offset = 0.4)) { coincident([arc3.center, arc1.center]) tangent([arc1, arc2]) tangent([arc3, arc4]) - angle([line2, line3]) == 85 + angleDimension(lines = [line2, line3], labelPosition = [0.12in, 0.16in], sector = 3) == 85 distance([line2.start, line2.end]) == 1.4 coincident([line2.start, arc4.center]) } diff --git a/content/pages/docs/kcl-samples/artificial-heart/plumbing.kcl b/content/pages/docs/kcl-samples/artificial-heart/plumbing.kcl index 126940a7..cd061923 100644 --- a/content/pages/docs/kcl-samples/artificial-heart/plumbing.kcl +++ b/content/pages/docs/kcl-samples/artificial-heart/plumbing.kcl @@ -17,7 +17,7 @@ sketch002 = sketch(on = XZ) { coincident([line3.start, line1.start]) horizontal([line3.end, ORIGIN]) horizontal(line3) - angle([line1, line3]) == 45 + angleDimension(lines = [line1, line3], sector = 1) == 45 distance([line1.start, line1.end]) == 1.65in radius(arc1) == 3.2 / 2 circle1 = circle(start = [var 1.18in, var 0.93in], center = [var 0in, var 0in], construction = true) diff --git a/content/pages/docs/kcl-samples/artificial-heart/stator.kcl b/content/pages/docs/kcl-samples/artificial-heart/stator.kcl index 94b17827..cc829107 100644 --- a/content/pages/docs/kcl-samples/artificial-heart/stator.kcl +++ b/content/pages/docs/kcl-samples/artificial-heart/stator.kcl @@ -42,7 +42,7 @@ sketch002 = sketch(on = XZ) { symmetric([line2, line1], axis = line3) symmetric([arc2, arc1], axis = line3) tangent([arc3, arc1]) - angle([line1, line2]) == 180 - 30 + angleDimension(lines = [line1, line2], sector = 2, labelPosition = [0in, 1.16in]) == 30 tangent([arc5, arc6]) verticalDistance([line3.start, arc2.center]) == 1 horizontalDistance([arc1.center, arc2.center]) == .1 diff --git a/content/pages/docs/kcl-samples/axial-fan/fan-housing.kcl b/content/pages/docs/kcl-samples/axial-fan/fan-housing.kcl index c350162b..e37c8b70 100644 --- a/content/pages/docs/kcl-samples/axial-fan/fan-housing.kcl +++ b/content/pages/docs/kcl-samples/axial-fan/fan-housing.kcl @@ -201,7 +201,7 @@ sketch003 = sketch(on = XY) { coincident([line6.end, line4.start]) equalLength([line5, line6]) verticalDistance([line5.start, line5.end]) == 6 - angle([line3, line2]) == 60 + angleDimension(lines = [line3, line2], sector = 4, labelPosition = [7.16mm, 24.34mm]) == 120deg horizontalDistance([line1.start, arc4.center]) == 0.02mm coincident([arc4.center, line4]) } diff --git a/content/pages/docs/kcl-samples/cycloidal-gear/main.kcl b/content/pages/docs/kcl-samples/cycloidal-gear/main.kcl index 02f679a7..35dd98ac 100644 --- a/content/pages/docs/kcl-samples/cycloidal-gear/main.kcl +++ b/content/pages/docs/kcl-samples/cycloidal-gear/main.kcl @@ -40,8 +40,8 @@ outerProfile = sketch(on = XY) { vertical(c2ToC1) vertical(c1ToC6) - angle([baseline, c2ToC3]) == 150deg - angle([baseline, c4ToC5]) == 30deg + angleDimension(lines = [baseline, c2ToC3], sector = 3, labelPosition = [-1.23in, -0.83in]) == 150deg + angleDimension(lines = [baseline, c4ToC5], sector = 1, labelPosition = [-0.22in, 0.19in]) == 30deg parallel([c2ToC3, c3ToC4]) parallel([c4ToC5, c5ToC6]) diff --git a/content/pages/docs/kcl-samples/field-monitor-stand/main.kcl b/content/pages/docs/kcl-samples/field-monitor-stand/main.kcl index b9a92bcc..d92925b3 100644 --- a/content/pages/docs/kcl-samples/field-monitor-stand/main.kcl +++ b/content/pages/docs/kcl-samples/field-monitor-stand/main.kcl @@ -60,7 +60,7 @@ bodyProfile = sketch(on = YZ) { distance([line2.start, line2.end]) == plateLength distance([line3.start, line3.end]) == width distance([line6.start, line6.end]) == width - angle([line1, line2]) == plateAngle + angleDimension(lines = [line1, line2], sector = 1, labelPosition = [3.15mm, 3.38mm]) == plateAngle } bodyRegion = region(segments = [bodyProfile.line1, bodyProfile.line2]) diff --git a/content/pages/docs/kcl-samples/m4-insert/main.kcl b/content/pages/docs/kcl-samples/m4-insert/main.kcl index d71411af..cc24c8b2 100644 --- a/content/pages/docs/kcl-samples/m4-insert/main.kcl +++ b/content/pages/docs/kcl-samples/m4-insert/main.kcl @@ -70,7 +70,7 @@ insertProfileSketch = sketch(on = XY) { horizontalDistance([midWall.start, centerGuide.end]) == insertGuideDiameter horizontalDistance([bottomBridge.end, centerGuide.end]) == insertLowerBandDiameter / 2 verticalDistance([innerWall.end, innerWall.start]) == insertOverallHeight - angle([midWall, taperFlank]) == taperAngle + angleDimension(lines = [midWall, taperFlank], sector = 1, labelPosition = [-2.83mm, -6.02mm]) == taperAngle } insertProfileRegion = region(point = [-3.1475mm, -1.14mm], sketch = insertProfileSketch) diff --git a/content/pages/docs/kcl-samples/multi-axis-robot/robot-arm-base.kcl b/content/pages/docs/kcl-samples/multi-axis-robot/robot-arm-base.kcl index eb7893ee..8f64fd69 100644 --- a/content/pages/docs/kcl-samples/multi-axis-robot/robot-arm-base.kcl +++ b/content/pages/docs/kcl-samples/multi-axis-robot/robot-arm-base.kcl @@ -49,7 +49,7 @@ sketch004 = sketch(on = XY) { horizontal([line14.end, ORIGIN]) horizontal(line14) horizontal(line13) - angle([line13, line5]) == 34 + angleDimension(lines = [line13, line5], sector = 1) == 34 line15 = line(start = [var 0in, var 0in], end = [var 0in, var 4.46in], construction = true) coincident([line15.start, line5.start]) vertical([line15.end, ORIGIN]) @@ -58,13 +58,13 @@ sketch004 = sketch(on = XY) { vertical([line16.end, ORIGIN]) vertical(line16) vertical(line15) - angle([line6, line15]) == 34 - angle([line15, line7]) == 34 - angle([line8, line14]) == 34 - angle([line14, line9]) == 34 - angle([line10, line16]) == 34 - angle([line16, line11]) == 34 - angle([line12, line13]) == 34 + angleDimension(lines = [line6, line15], sector = 1) == 34 + angleDimension(lines = [line15, line7], sector = 1) == 34 + angleDimension(lines = [line8, line14], sector = 1) == 34 + angleDimension(lines = [line14, line9], sector = 1) == 34 + angleDimension(lines = [line10, line16], sector = 1) == 34 + angleDimension(lines = [line16, line11], sector = 1) == 34 + angleDimension(lines = [line12, line13], sector = 1) == 34 distance([line12.start, line12.end]) == 5.35 circle1 = circle(start = [var 4.54in, var 2.61in], center = [var 4.43in, var 2.99in]) coincident([circle1.center, line5.end]) diff --git a/content/pages/docs/kcl-samples/wheel-hub/main.kcl b/content/pages/docs/kcl-samples/wheel-hub/main.kcl index aad05ae4..199e1bdd 100644 --- a/content/pages/docs/kcl-samples/wheel-hub/main.kcl +++ b/content/pages/docs/kcl-samples/wheel-hub/main.kcl @@ -163,7 +163,7 @@ trimProfile = sketch(on = XY) { startOffsetGuide.end ]) == rotorBore / 2 distance([line1.start, line1.end]) == lugSpacing / 3 - angle([startOffsetGuide, line1]) == 10deg + angleDimension(lines = [startOffsetGuide, line1], sector = 1, labelPosition = [2.17in, -0.69in]) == 10deg distance([line2.start, line2.end]) == hubSpacing * 1.5 } diff --git a/content/pages/docs/kcl-samples/zoo-logo/main.kcl b/content/pages/docs/kcl-samples/zoo-logo/main.kcl index 5a5178fb..3c454ef6 100644 --- a/content/pages/docs/kcl-samples/zoo-logo/main.kcl +++ b/content/pages/docs/kcl-samples/zoo-logo/main.kcl @@ -187,7 +187,7 @@ logoSketch = sketch(on = XY) { parallel([o1Guide01, o1Guide02]) equalLength([o1Guide01, o1Guide02]) - angle([frameBottom, o1Line01]) == 47deg + angleDimension(lines = [frameBottom, o1Line01], sector = 1, labelPosition = [1.06in, 0.06in]) == 47deg horizontalDistance([frameLeft.end, o1GuideArc04.center]) == logoHeight * 1.448 verticalDistance([frameLeft.end, o1GuideArc04.center]) == logoHeight * 0.5 radius(o1Arc03) == logoHeight * 0.5 @@ -269,7 +269,7 @@ logoSketch = sketch(on = XY) { horizontalDistance([o2Arc04.center, frameRight.start]) == logoHeight * 0.5 verticalDistance([frameRight.start, o2Arc04.center]) == logoHeight * 0.5 distance([o2GuideArc04.end, o2GuideArc04.start]) == logoHeight * 0.1 - angle([frameBottom, o2Line03]) == 47deg + angleDimension(lines = [frameBottom, o2Line03], sector = 1, labelPosition = [2.2in, 0.04in]) == 47deg radius(o2Arc02) == logoHeight * 0.5 radius(o2Arc03) == logoHeight * 0.27 diff --git a/content/pages/docs/kcl-std/functions/std-sketch-patternTransform2d.md b/content/pages/docs/kcl-std/functions/std-sketch-patternTransform2d.md index 1d52fc00..2296d936 100644 --- a/content/pages/docs/kcl-std/functions/std-sketch-patternTransform2d.md +++ b/content/pages/docs/kcl-std/functions/std-sketch-patternTransform2d.md @@ -12,7 +12,7 @@ patternTransform2d( @sketches: [Sketch; 1+], instances: number(_), transform: fn(number(_)): { }, - useOriginal?: boolean, + useOriginal?: bool, ): [Sketch; 1+] ``` @@ -25,7 +25,7 @@ patternTransform2d( | `sketches` | [[`Sketch`](/docs/kcl-std/types/std-types-Sketch); 1+] | The sketch(es) to duplicate. | Yes | | `instances` | [`number(_)`](/docs/kcl-std/types/std-types-number) | The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes | | `transform` | [`fn(number(_)): { }`](/docs/kcl-std/types/std-types-fn) | How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples. | Yes | -| `useOriginal` | `boolean` | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No | +| `useOriginal` | [`bool`](/docs/kcl-std/types/std-types-bool) | If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. | No | ### Returns diff --git a/content/pages/docs/kcl-std/functions/std-sketch-region.md b/content/pages/docs/kcl-std/functions/std-sketch-region.md index 60a68c15..65478fd8 100644 --- a/content/pages/docs/kcl-std/functions/std-sketch-region.md +++ b/content/pages/docs/kcl-std/functions/std-sketch-region.md @@ -22,6 +22,10 @@ segment from its start point to the intersection with the second segment, then turning at each intersection using `direction` until returning to the first segment. +For a single closed segment such as a circle, pass only that segment. +`intersectionIndex` and `direction` are unnecessary for one loop; use them +to disambiguate a boundary traced from multiple segments. + As a fallback, use the `point` parameter to select the closed boundary that contains a given point. When using a 2D point rather than a point from the sketch, provide the `sketch` parameter to specify which sketch the region is @@ -37,8 +41,8 @@ refer to that point to create the region. |----------|------|-------------|----------| | `point` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) or [`Segment`](/docs/kcl-std/types/std-types-Segment) | A fallback point that is within the region's boundary. | No | | `segments` | [[`Segment`](/docs/kcl-std/types/std-types-Segment); 1+] | The first two segments that form the region's boundary. In case of a circle, the one circle segment that forms the region. This is the preferred way to create a region. | No | -| `intersectionIndex` | [`number(_)`](/docs/kcl-std/types/std-types-number) | Index of the intersection of the first segment with the second segment to use as the region's boundary. The default is `-1`, which uses the last intersection. This is only used when the `segments` argument is provided. | No | -| `direction` | [`string`](/docs/kcl-std/types/std-types-string) | `CCW` for counterclockwise, `CW` for clockwise. Default is `CCW`. This is only used when the `segments` argument is provided. | No | +| `intersectionIndex` | [`number(_)`](/docs/kcl-std/types/std-types-number) | Index of the intersection of the first segment with the second segment to use as the region's boundary. The default is `-1`, which uses the last intersection. This is usually only needed when two or more `segments` are provided. | No | +| `direction` | [`string`](/docs/kcl-std/types/std-types-string) | `CCW` for counterclockwise, `CW` for clockwise. Default is `CCW`. This is usually only needed when two or more `segments` are provided. | No | | `sketch` | [`any`](/docs/kcl-std/types/std-types-any) | The sketch that the region is from. This is required when point is a [`Point2d`](/docs/kcl-std/types/std-types-Point2d). | No | ### Returns diff --git a/content/pages/docs/kcl-std/functions/std-solver-angle.md b/content/pages/docs/kcl-std/functions/std-solver-angle.md index a1195c33..088f0a14 100644 --- a/content/pages/docs/kcl-std/functions/std-solver-angle.md +++ b/content/pages/docs/kcl-std/functions/std-solver-angle.md @@ -5,12 +5,19 @@ excerpt: "Constrain lines to meet at a given angle." layout: manual --- +**WARNING:** This function is deprecated as of KCL 2.0. + Constrain lines to meet at a given angle. ```kcl -solver::angle(@input: [Segment; 2]) +solver::angle( + @input: [Segment; 2], + labelPosition?: Point2d, +) ``` +Deprecated as of KCL 2.0. Use `angleDimension` for new angle constraints. + The angle is measured counterclockwise from the first line to the second line, modulo 180 degrees, so the order of the lines matters: `angle([a, b]) == 30deg` is equivalent to `angle([b, a]) == 150deg`. @@ -22,6 +29,7 @@ which end of each line segment is its start or end. | Name | Type | Description | Required | |----------|------|-------------|----------| | `input` | [[`Segment`](/docs/kcl-std/types/std-types-Segment); 2] | The two line segments whose relative angle should match the value set with `==`, measured counterclockwise from the first line to the second, modulo 180 degrees. The order of the lines matters. | Yes | +| `labelPosition` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The desired position of the constraint label. | No | ### Examples diff --git a/content/pages/docs/kcl-std/functions/std-solver-angleDimension.md b/content/pages/docs/kcl-std/functions/std-solver-angleDimension.md new file mode 100644 index 00000000..cf86cc33 --- /dev/null +++ b/content/pages/docs/kcl-std/functions/std-solver-angleDimension.md @@ -0,0 +1,73 @@ +--- +title: "solver::angleDimension" +subtitle: "Function in std::solver" +excerpt: "Constrain the angle in the selected sector between two lines." +layout: manual +--- + +Constrain the angle in the selected sector between two lines. + +```kcl +solver::angleDimension( + lines: [Segment; 2], + sector: number(_), + inverse?: bool, + labelPosition?: Point2d, +) +``` + + + +### Arguments + +| Name | Type | Description | Required | +|----------|------|-------------|----------| +| `lines` | [[`Segment`](/docs/kcl-std/types/std-types-Segment); 2] | The ordered pair of line segments whose selected angle sector should match the value set with `==`. A line's positive direction runs from its start point to its end point; its negative direction is the reverse. | Yes | +| `sector` | [`number(_)`](/docs/kcl-std/types/std-types-number) | Which counterclockwise sweep about the line intersection to constrain: `1`, first line's positive direction to the second line's positive direction; `2`, second positive to first negative; `3`, first negative to second negative; or `4`, second negative to first positive. | Yes | +| `inverse` | [`bool`](/docs/kcl-std/types/std-types-bool) | Use the counterclockwise sweep from the selected sector's end direction to its start direction. For example, a `20deg` sweep with `inverse = false` becomes `340deg` with `inverse = true`. | No | +| `labelPosition` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The desired position of the constraint label. | No | + + +### Examples + +```kcl +normalProfile = sketch(on = XY) { + line1 = line(start = [var 0mm, var 0mm], end = [var 4mm, var 0mm]) + line2 = line(start = [var 0mm, var 0mm], end = [var 2mm, var 3.464mm]) + line3 = line(start = [var 2mm, var 3.464mm], end = [var 4mm, var 0mm]) + coincident([line1.start, line2.start]) + coincident([line2.end, line3.start]) + coincident([line3.end, line1.end]) + angleDimension(lines = [line1, line2], sector = 1, inverse = false) == 60deg +} + +inverseProfile = sketch(on = XY) { + line1 = line(start = [var 7mm, var 0mm], end = [var 11mm, var 0mm]) + line2 = line(start = [var 7mm, var 0mm], end = [var 9mm, var 3.464mm]) + line3 = line(start = [var 9mm, var 3.464mm], end = [var 11mm, var 0mm]) + coincident([line1.start, line2.start]) + coincident([line2.end, line3.start]) + coincident([line3.end, line1.end]) + angleDimension(lines = [line1, line2], sector = 1, inverse = true) == 300deg +} + +normalSolid = extrude(region(point = [2mm, 1mm], sketch = normalProfile), length = 2) +inverseSolid = extrude(region(point = [9mm, 1mm], sketch = inverseProfile), length = 2) + +``` + + + + + + diff --git a/content/pages/docs/kcl-std/index.md b/content/pages/docs/kcl-std/index.md index ec5b6c34..c6564f8f 100644 --- a/content/pages/docs/kcl-std/index.md +++ b/content/pages/docs/kcl-std/index.md @@ -166,6 +166,7 @@ layout: manual * [`union`](/docs/kcl-std/functions/std-solid-union) * [**std::solver**](/docs/kcl-std/modules/std-solver) * [`solver::angle`](/docs/kcl-std/functions/std-solver-angle) + * [`solver::angleDimension`](/docs/kcl-std/functions/std-solver-angleDimension) * [`solver::arc`](/docs/kcl-std/functions/std-solver-arc) * [`solver::circle`](/docs/kcl-std/functions/std-solver-circle) * [`solver::coincident`](/docs/kcl-std/functions/std-solver-coincident) @@ -292,3 +293,7 @@ See also the [types overview](/docs/kcl-lang/types) * [`mm`](/docs/kcl-std/types/std-types-mm) * [`rad`](/docs/kcl-std/types/std-types-rad) * [`yd`](/docs/kcl-std/types/std-types-yd) +* [**std::view**](/docs/kcl-std/modules/std-view) Experimental + * [`view::Orientation`](/docs/kcl-std/types/std-view-Orientation) Experimental + * [`view::Projection`](/docs/kcl-std/types/std-view-Projection) Experimental + * [`view::Visibility`](/docs/kcl-std/types/std-view-Visibility) Experimental diff --git a/content/pages/docs/kcl-std/modules/std-solver.md b/content/pages/docs/kcl-std/modules/std-solver.md index b6fad3cd..645cf2a9 100644 --- a/content/pages/docs/kcl-std/modules/std-solver.md +++ b/content/pages/docs/kcl-std/modules/std-solver.md @@ -47,6 +47,7 @@ functions, because those are what actually constrain the solved result. * [`solver::ORIGIN`](/docs/kcl-std/consts/std-solver-ORIGIN) * [`solver::angle`](/docs/kcl-std/functions/std-solver-angle) +* [`solver::angleDimension`](/docs/kcl-std/functions/std-solver-angleDimension) * [`solver::arc`](/docs/kcl-std/functions/std-solver-arc) * [`solver::circle`](/docs/kcl-std/functions/std-solver-circle) * [`solver::coincident`](/docs/kcl-std/functions/std-solver-coincident) diff --git a/content/pages/docs/kcl-std/modules/std-view.md b/content/pages/docs/kcl-std/modules/std-view.md new file mode 100644 index 00000000..bc67657e --- /dev/null +++ b/content/pages/docs/kcl-std/modules/std-view.md @@ -0,0 +1,24 @@ +--- +title: "view" +subtitle: "Module in std" +excerpt: "Named views: cameras and visibility sets defined in KCL. " +layout: manual +--- + +**WARNING:** This module is experimental and may change or be removed. + +Named views: cameras and visibility sets defined in KCL. + +A named view pairs a camera with a set of visible objects, so consumers +such as the modeling app and STEP export can reproduce it. This version of +the module provides the enums named views are built from; the view and +camera constructors arrive in a later version. + + + + +## Types + +* [`view::Orientation`](/docs/kcl-std/types/std-view-Orientation) +* [`view::Projection`](/docs/kcl-std/types/std-view-Projection) +* [`view::Visibility`](/docs/kcl-std/types/std-view-Visibility) diff --git a/content/pages/docs/kcl-std/modules/std.md b/content/pages/docs/kcl-std/modules/std.md index 6812c3c0..ddccea46 100644 --- a/content/pages/docs/kcl-std/modules/std.md +++ b/content/pages/docs/kcl-std/modules/std.md @@ -35,6 +35,7 @@ You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL gui * [`types`](/docs/kcl-std/modules/std-types) * [`units::units`](/docs/kcl-std/modules/std-units) * [`vector::vector`](/docs/kcl-std/modules/std-vector) +* [`view::view`](/docs/kcl-std/modules/std-view) ## Functions and constants diff --git a/content/pages/docs/kcl-std/types/std-view-Orientation.md b/content/pages/docs/kcl-std/types/std-view-Orientation.md new file mode 100644 index 00000000..ed6acfd3 --- /dev/null +++ b/content/pages/docs/kcl-std/types/std-view-Orientation.md @@ -0,0 +1,40 @@ +--- +title: "view::Orientation" +subtitle: "Type in std::view" +excerpt: "A standard camera orientation for a named view." +layout: manual +--- + +**WARNING:** This type is experimental and may change or be removed. + +A standard camera orientation for a named view. + +```kcl +type Orientation { + | Front + | Back + | Left + | Right + | Top + | Bottom + | Isometric +} +``` + +The six axis-aligned orientations name the side of the model the camera +looks at; `Isometric` is the standard three-quarter view. + + +### Variants + +| Variant | Description | +|---------|-------------| +| `Front` | The camera looks at the front of the model. | +| `Back` | The camera looks at the back of the model. | +| `Left` | The camera looks at the left side of the model. | +| `Right` | The camera looks at the right side of the model. | +| `Top` | The camera looks down at the top of the model. | +| `Bottom` | The camera looks up at the bottom of the model. | +| `Isometric` | The standard three-quarter view, showing three faces of the model at once. | + + diff --git a/content/pages/docs/kcl-std/types/std-view-Projection.md b/content/pages/docs/kcl-std/types/std-view-Projection.md new file mode 100644 index 00000000..f9c6e9ba --- /dev/null +++ b/content/pages/docs/kcl-std/types/std-view-Projection.md @@ -0,0 +1,29 @@ +--- +title: "view::Projection" +subtitle: "Type in std::view" +excerpt: "The camera projection of a named view." +layout: manual +--- + +**WARNING:** This type is experimental and may change or be removed. + +The camera projection of a named view. + +```kcl +type Projection { + | Orthographic + | Perspective +} +``` + + + + +### Variants + +| Variant | Description | +|---------|-------------| +| `Orthographic` | An object's projected size is independent of its distance from the camera, and parallel edges remain parallel; the convention of engineering drawings. | +| `Perspective` | Apparent size decreases with distance from the camera, as a physical camera sees; parallel edges converge toward vanishing points. | + + diff --git a/content/pages/docs/kcl-std/types/std-view-Visibility.md b/content/pages/docs/kcl-std/types/std-view-Visibility.md new file mode 100644 index 00000000..7b38bcaf --- /dev/null +++ b/content/pages/docs/kcl-std/types/std-view-Visibility.md @@ -0,0 +1,29 @@ +--- +title: "view::Visibility" +subtitle: "Type in std::view" +excerpt: "Whether a named view shows or hides objects by default." +layout: manual +--- + +**WARNING:** This type is experimental and may change or be removed. + +Whether a named view shows or hides objects by default. + +```kcl +type Visibility { + | Show + | Hide +} +``` + + + + +### Variants + +| Variant | Description | +|---------|-------------| +| `Show` | Objects are shown unless the view hides them. | +| `Hide` | Objects are hidden unless the view shows them. | + +