Last active
August 4, 2025 10:58
-
-
Save felipesabino/4c9a2f677b783624ee5695de1147d7bc to your computer and use it in GitHub Desktop.
replicad-tables-demo.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // workbench: https://studio.replicad.xyz/workbench#code=UEsDBAoAAAAIAAh5A1v1i531AwQAAOoLAAAHAAAAY29kZS5qc81WS2%252FjNhC%252B61cMcpI3Wj%252FS7B7sboHUMLpbLBDDDtqD4QMj0RYbRjJIuc428H%252FvkENSlJwWWPTSHGJx%252BM3HeZN5XekGXqFQ7LRU9R88b0RdZdB%252Bz9kzVyyziAwaxSotWcPhDJ9A8YMUOStmSZJbooLv2FE2S6bYs0bAawIg%252Bf53UTTlFD5ktPzMxb5spnA7NgLNWeMAH4PAQ6zKXoliLf7iU5iMLULVJ42LG%252FOd1zJ867KOvJjCjknN%252FcYvyDJFB46cKBr0wsgWkj%252FzqtF%252B7zxzzjwzUaEPqcrgEBw6D%252BDTT%252BhXghwAoxF85Xttv0lJIghd1CmpDL33nmMY%252FA%252BSEIDBzJOuURSRmpMNKu1rdDiIdmD1AIYhVen7vtroJoM3hX0bnUX2n%252BRoSMkOHI3ZHTW%252FkzLdyAz0FlEWIXYQLHQBH9gSMH99VZPUeX0QXKd2KxxukhsWJrth4esggvaTOHAWn1u7e1a19dHapnhzVBUc8Lf51gLIMM8IHIupr2IR%252FsjE5s4UUJLgx%252FJu9bBOkt2xsmyQl0woLJcU%252Bwgz16bdkrpMuyiZbksplUMpKv5Qp5txBqdtT3Z6Wzbuy8aRLJe15p5cP%252FEmL%252B%252BrpWRVEPIXbIWCp1SRXVfPkUe20P%252FFG9xHXzp%252Bh%252FKk3KW3H%252BIzfHEcasmUqw4kyeA2OmF0M%252BizvLc0sWm2XeyB1h7H%252F%252F8J69mWyGox%252F7JcrP34dO6boWOjrd2woeZTXONsNaPA7m3G21ni%252BgpLGwcxTyeD4a5WC5aXqSteTwCtOn0MzWFRhZ%252FjPBBkRqVMtkUpCfZlmOdjhZNMsUIcW2tJ45Fp7q2NptE4wGcByqq9NNgfPo5hRKR2ptBu7k%252FdWI%252FRQ0hNQASKxjP8%252BdGpgLi%252B9l1NSsPDUZepscTkx6TCl4yAd3QsjYxz6zxpdpxvh1XkOw0qmlDtaCL6Xih6Hrj4PNYvIT6P6EAhqv3P9UuLyHGkcYUYAx3Sqhe0dcMPK4rcyBj0xvbcbRtLO%252FFTFD%252BF8bOqoNrwBVBOoNwGGQkgb0FUlya67gagaetD4EF2LPq4q3fBsEHYj0slCKmnQvt0Oz6iWWUuUBlsJtiQGUy2b6nkrcq8qzK5UGnLVWGdtNnNo5W7GC6uhu9y5%252FsOcr%252Fdn36lR1fgP1S1uZxW978u5g9f7kN%252F9y6%252FUOj9rv6PVZvXqrK7G2tlhMGBlqFl1yQ72ffNBWYSY0p6SF2AbrYeUfADsUR9l9sXLVpQ8dPFQzcl%252BwZDWddPd01KjNGoeoU%252FhRaPEnNUiqLglX0Jd9%252FPYTpaSnoeuTSQ168Uv6mjwMutUfUTf%252FhmZFdF3eirDCrUxtVnOuUrXjn6Cs5ZlyAY49C%252F0boD35qs%252Fw1QSwECFAAKAAAACAAIeQNb9Yud9QMEAADqCwAABwAAAAAAAAAAAAAAAAAAAAAAY29kZS5qc1BLBQYAAAAAAQABADUAAAAoBAAAAAA%253D | |
| // instagram: https://www.instagram.com/p/DM0_5q2qa01/ | |
| const { drawProjection, ProjectionCamera, draw, translate } = replicad; | |
| const defaultParams = { | |
| legWidth: 5, | |
| legHeight: 40, | |
| seatWidth: 60, | |
| seatHeight: 5, | |
| gridSize: 100, | |
| rows: 12, | |
| cols: 12, | |
| showProjection: true, | |
| showGrid: true, | |
| rotateGridElements: true, | |
| }; | |
| const main = (r, params = {}) => { | |
| // Legs | |
| const l = legs(params.legWidth, params.legHeight, params.seatWidth); | |
| // Seat | |
| const s = seat(params.seatWidth, params.seatHeight) | |
| .translate(-params.seatWidth/2, -params.seatWidth/2, params.legHeight); | |
| let shape = fuseAll([l, s]); | |
| if (params.showGrid) { | |
| shape = fuseAll(gridCopies(shape, params.rows, params.cols, params.gridSize, params.rotateGridElements)); | |
| } | |
| if (params.showProjection) { | |
| return prettyProjection(shape); | |
| } else { | |
| return shape; | |
| } | |
| // | |
| }; | |
| // PARTS | |
| function chairLeg(w, h, seatWidth) { | |
| const shape = draw() | |
| .lineTo([0, w]) | |
| .lineTo([w, w]) | |
| .lineTo([w, 0]) | |
| .lineTo([0, 0]) | |
| .close() | |
| .sketchOnPlane() | |
| .extrude(h); | |
| return shape; | |
| } | |
| function legs(w, h, seatWidth) { | |
| const leg = chairLeg(w, h) | |
| .rotate(45); | |
| return fuseAll(polarCopies(leg, 4, seatWidth/2)) | |
| .rotate(-45); | |
| } | |
| function seat(w, h) { | |
| return draw() | |
| .lineTo([0, w]) | |
| .lineTo([w, w]) | |
| .lineTo([w, 0]) | |
| .lineTo([0, 0]) | |
| .close() | |
| .sketchOnPlane() | |
| .extrude(h); | |
| } | |
| // RECIPES | |
| const fuseAll = (shapes) => { | |
| let result = shapes[0]; | |
| shapes.slice(1).forEach((shape) => { | |
| result = result.fuse(shape); | |
| }); | |
| return result; | |
| }; | |
| const polarCopies = (shape, count, radius) => { | |
| const base = shape.translate(0, radius); | |
| const angle = 360 / count; | |
| const copies = []; | |
| for (let i = 0; i < count; i++) { | |
| copies.push(base.clone().rotate(i * angle)); | |
| } | |
| return copies; | |
| }; | |
| const gridCopies = (shape, rows, cols, gridSize, rotate) => { | |
| const copies = []; | |
| const bbox = shape.boundingBox; | |
| const center = bbox.center; | |
| const angleStepR = 360/rows; | |
| const angleStepC = 360/cols; | |
| for (let r = 0; r < rows; r++) { | |
| for (let c = 0; c < cols; c++) { | |
| let base; | |
| if (rotate) { | |
| // .rotate(r*angleStep) | |
| base = shape | |
| .clone() | |
| .rotate(r*angleStepR, center, [1, 0, 1]) | |
| .rotate(c*angleStepC, center, [1, 1, 1]) | |
| .translate(r * gridSize, c * gridSize); | |
| } else { | |
| base = shape | |
| .clone() | |
| .translate(r * gridSize, c * gridSize); | |
| } | |
| copies.push(base); | |
| } | |
| } | |
| return copies; | |
| }; | |
| // PROJECTIO | |
| const prettyProjection = (shape) => { | |
| const bbox = shape.boundingBox; | |
| const center = bbox.center; | |
| const corner = [ | |
| bbox.center[0],// + bbox.width, | |
| bbox.center[1],// + bbox.height, | |
| bbox.center[2] + bbox.depth, | |
| ]; | |
| const camera = new ProjectionCamera(corner).lookAt(center); | |
| const { visible, hidden } = drawProjection(shape, camera); | |
| return [ | |
| { shape: hidden, strokeType: "dots", name: "Hidden Lines" }, | |
| { shape: visible, name: "Visible Lines" }, | |
| ]; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment