| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | // Dual-Basin Utility Sink | 
					
						
							|  |  |  | // A stainless steel sink unit with dual rectangular basins and six under-counter storage compartments. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | // set units | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | @settings(defaultLengthUnit = mm) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // globals | 
					
						
							|  |  |  | tableHeight = 850 | 
					
						
							|  |  |  | tableWidth = 3400 | 
					
						
							|  |  |  | tableDepth = 400 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | profileThickness = 13 | 
					
						
							|  |  |  | metalThickness = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | blockCount = 3 | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | blockWidth = (tableWidth - profileThickness) / 3 | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | blockHeight = tableHeight - metalThickness - 0.5 | 
					
						
							|  |  |  | blockDepth = tableDepth - profileThickness | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | blockSubdivisionCount = 2 | 
					
						
							|  |  |  | blockSubdivisionWidth = blockWidth / blockSubdivisionCount | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Geometry | 
					
						
							|  |  |  | floorPlane = startSketchOn(XY) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // legs | 
					
						
							|  |  |  | legHeight = blockHeight - profileThickness | 
					
						
							|  |  |  | legCount = blockCount + 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | legBody = startProfileAt([0, 0], floorPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = profileThickness) | 
					
						
							|  |  |  |   |> xLine(length = profileThickness) | 
					
						
							|  |  |  |   |> yLine(length = -profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = legCount, distance = blockWidth) | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth) | 
					
						
							|  |  |  |   |> extrude(length = legHeight) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // lower belt | 
					
						
							|  |  |  | lowerBeltHeightAboveTheFloor = 150 | 
					
						
							|  |  |  | lowerBeltLengthX = blockWidth - profileThickness | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | lowerBeltPlane = startSketchOn(offsetPlane(XY, offset = lowerBeltHeightAboveTheFloor)) | 
					
						
							|  |  |  | lowerBeltBodyX = startProfileAt([profileThickness, 0], lowerBeltPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = profileThickness) | 
					
						
							|  |  |  |   |> xLine(length = lowerBeltLengthX) | 
					
						
							|  |  |  |   |> yLine(length = -profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth) | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth) | 
					
						
							|  |  |  |   |> extrude(length = profileThickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | lowerBeltLengthY = blockDepth - profileThickness | 
					
						
							|  |  |  | lowerBeltBodyY = startProfileAt([0, profileThickness], lowerBeltPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = lowerBeltLengthY) | 
					
						
							|  |  |  |   |> xLine(length = profileThickness) | 
					
						
							|  |  |  |   |> yLine(length = -lowerBeltLengthY) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> extrude(length = profileThickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // pillars | 
					
						
							|  |  |  | pillarHeightAboveTheFloor = lowerBeltHeightAboveTheFloor + profileThickness | 
					
						
							|  |  |  | pillarPlane = startSketchOn(offsetPlane(XY, offset = pillarHeightAboveTheFloor)) | 
					
						
							|  |  |  | pillarTotalHeight = blockHeight - profileThickness - pillarHeightAboveTheFloor | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | pillarBody = startProfileAt([blockSubdivisionWidth, 0], pillarPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = profileThickness) | 
					
						
							|  |  |  |   |> xLine(length = profileThickness) | 
					
						
							|  |  |  |   |> yLine(length = -profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth) | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth) | 
					
						
							|  |  |  |   |> extrude(length = pillarTotalHeight) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // upper belt | 
					
						
							|  |  |  | upperBeltPlane = startSketchOn(offsetPlane(XY, offset = blockHeight)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | upperBeltBodyX = startProfileAt([0, 0], upperBeltPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = profileThickness) | 
					
						
							|  |  |  |   |> xLine(length = tableWidth) | 
					
						
							|  |  |  |   |> yLine(length = -profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth) | 
					
						
							|  |  |  |   |> extrude(length = -profileThickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | upperBeltLengthY = blockDepth - profileThickness | 
					
						
							|  |  |  | upperBeltBodyY = startProfileAt([0, profileThickness], upperBeltPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = upperBeltLengthY) | 
					
						
							|  |  |  |   |> xLine(length = profileThickness) | 
					
						
							|  |  |  |   |> yLine(length = -upperBeltLengthY) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> extrude(length = -profileThickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // sink | 
					
						
							|  |  |  | tableTopPlane = startSketchOn(offsetPlane(XY, offset = tableHeight)) | 
					
						
							|  |  |  | tableTopBody = startProfileAt([0, 0], tableTopPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = tableDepth) | 
					
						
							|  |  |  |   |> xLine(length = tableWidth) | 
					
						
							|  |  |  |   |> yLine(length = -tableDepth) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> extrude(length = -metalThickness) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sinkCount = 2 | 
					
						
							|  |  |  | sinkWidth = 1000 | 
					
						
							|  |  |  | sinkLength = 250 | 
					
						
							|  |  |  | sinkDepth = 200 | 
					
						
							|  |  |  | sinkOffsetFront = 40 | 
					
						
							|  |  |  | sinkOffsetLeft = 350 | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | sinkSpacing = tableWidth - sinkWidth - (sinkOffsetLeft * 2) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | sinkPlaneOutside = startSketchOn(tableTopBody, 'START') | 
					
						
							|  |  |  | sinkBodyOutside = startProfileAt([-sinkOffsetLeft, sinkOffsetFront], sinkPlaneOutside) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = sinkLength) | 
					
						
							|  |  |  |   |> xLine(length = -sinkWidth) | 
					
						
							|  |  |  |   |> yLine(length = -sinkLength) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [-1, 0], instances = sinkCount, distance = sinkSpacing) | 
					
						
							|  |  |  |   |> extrude(length = sinkDepth) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sinkPlaneInside = startSketchOn(tableTopBody, 'END') | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | sinkBodyInside = startProfileAt([ | 
					
						
							|  |  |  |        sinkOffsetLeft + metalThickness, | 
					
						
							|  |  |  |        sinkOffsetFront + metalThickness | 
					
						
							|  |  |  |      ], sinkPlaneInside) | 
					
						
							|  |  |  |   |> yLine(length = sinkLength - (metalThickness * 2)) | 
					
						
							|  |  |  |   |> xLine(length = sinkWidth - (metalThickness * 2)) | 
					
						
							|  |  |  |   |> yLine(length = -sinkLength + metalThickness * 2) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing) | 
					
						
							|  |  |  |   |> extrude(length = -sinkDepth) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | // door panels | 
					
						
							|  |  |  | doorGap = 2 | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | doorWidth = blockSubdivisionWidth - profileThickness - (doorGap * 2) | 
					
						
							|  |  |  | doorStart = profileThickness + doorGap | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | doorHeightAboveTheFloor = pillarHeightAboveTheFloor + doorGap | 
					
						
							|  |  |  | doorHeight = blockHeight - doorHeightAboveTheFloor - profileThickness - doorGap | 
					
						
							|  |  |  | doorCount = blockCount * blockSubdivisionCount | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | doorPlane = startSketchOn(offsetPlane(XY, offset = doorHeightAboveTheFloor)) | 
					
						
							|  |  |  | doorBody = startProfileAt([doorStart, 0], doorPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = profileThickness) | 
					
						
							|  |  |  |   |> xLine(length = doorWidth) | 
					
						
							|  |  |  |   |> yLine(length = -profileThickness) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = doorCount, distance = blockSubdivisionWidth) | 
					
						
							|  |  |  |   |> extrude(length = doorHeight) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // side panels | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | panelWidth = blockDepth - profileThickness - (doorGap * 2) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | panelCount = doorCount + 1 | 
					
						
							|  |  |  | panelSpacing = tableWidth - profileThickness | 
					
						
							|  |  |  | panelBody = startProfileAt([0, doorStart], doorPlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = panelWidth) | 
					
						
							|  |  |  |   |> xLine(length = profileThickness) | 
					
						
							|  |  |  |   |> yLine(length = -panelWidth) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) | 
					
						
							|  |  |  |   |> close() | 
					
						
							|  |  |  |   |> patternLinear2d(axis = [1, 0], instances = 2, distance = panelSpacing) | 
					
						
							|  |  |  |   |> extrude(length = doorHeight) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | // handle | 
					
						
							|  |  |  | handleDepth = 40 | 
					
						
							|  |  |  | handleWidth = 120 | 
					
						
							|  |  |  | handleFillet = 20 | 
					
						
							|  |  |  | handleHeightAboveTheFloor = 780 | 
					
						
							|  |  |  | handleOffset = doorStart + doorWidth / 2 - (handleWidth / 2) | 
					
						
							|  |  |  | handleLengthSegmentA = handleDepth - handleFillet | 
					
						
							|  |  |  | handleLengthSegmentB = handleWidth - (handleFillet * 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | handlePlane = startSketchOn(offsetPlane(XY, offset = handleHeightAboveTheFloor)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | handleProfilePath = startProfileAt([0 + handleOffset, 0], handlePlane) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = -handleLengthSegmentA) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> tangentialArcTo([ | 
					
						
							|  |  |  |        handleFillet + handleOffset, | 
					
						
							|  |  |  |        -handleDepth | 
					
						
							|  |  |  |      ], %) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> xLine(length = handleLengthSegmentB) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  |   |> tangentialArcTo([ | 
					
						
							|  |  |  |        handleOffset + handleWidth, | 
					
						
							|  |  |  |        -handleLengthSegmentA | 
					
						
							|  |  |  |      ], %) | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   |> yLine(length = handleLengthSegmentA) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | handleSectionPlane = startSketchOn(XZ) | 
					
						
							|  |  |  | handleProfileSection = circle( | 
					
						
							|  |  |  |   handleSectionPlane, | 
					
						
							| 
									
										
										
										
											2025-03-30 10:06:36 -07:00
										 |  |  |   center = [ | 
					
						
							|  |  |  |     handleOffset, | 
					
						
							|  |  |  |     handleHeightAboveTheFloor | 
					
						
							|  |  |  |   ], | 
					
						
							|  |  |  |   radius = 2, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2025-03-27 10:57:01 -04:00
										 |  |  | handleBody = sweep(handleProfileSection, path = handleProfilePath) | 
					
						
							|  |  |  |   |> patternLinear3d(axis = [1, 0, 0], instances = doorCount, distance = blockSubdivisionWidth) |