@@ -122,11 +122,13 @@ npm run export --silent -- Box > box.stl
122122
123123``` typescript
124124Solid .cube (width , height , depth , { color? })
125+ Solid .roundedBox (width , height , depth , { color?, radius?, segments? })
125126Solid .cylinder (radius , height , { color?, angle? }) // angle in degrees
126127Solid .sphere (radius , { color?, angle? })
127128Solid .cone (radius , height , { color?, angle? })
128129Solid .prism (sides , radius , height , { color?, angle? })
129130Solid .trianglePrism (radius , height , { color? })
131+ Solid .text (text , { color?, size?, height?, curveSegments?, bevelEnabled? })
130132```
131133
132134### Custom Profile Prisms
@@ -159,6 +161,77 @@ Solid.revolutionSolidFromPath([straight(5), curve(2, 90), ...], { angle?, color?
159161
160162** Profile coordinates:** X=radius from center, Y=height, rotates around Y-axis
161163
164+ ### 3D Text Extrusion
165+
166+ Create 3D text shapes with customizable size and extrusion depth:
167+
168+ ``` typescript
169+ // Simple text
170+ const label = Solid .text (' Hello' , { size: 10 , height: 2 , color: ' blue' });
171+
172+ // Text with bevel (rounded edges)
173+ const logo = Solid .text (' LOGO' , { size: 15 , height: 3 , bevelEnabled: true , color: ' gold' });
174+
175+ // Text as cutter for engraving
176+ const plate = Solid .cube (50 , 20 , 5 , { color: ' gray' });
177+ const text = Solid .text (' ENGRAVED' , { size: 4 , height: 10 , color: ' gray' });
178+ const engraved = Solid .SUBTRACT (plate , text );
179+
180+ // Embossed text (raised text on surface)
181+ const base = Solid .cube (40 , 30 , 3 , { color: ' gray' });
182+ const embossText = Solid .text (' LOGO' , { size: 6 , height: 2 , color: ' gold' }).move ({ y: 3 }); // Position on top of base
183+ const embossed = Solid .UNION (base , embossText );
184+ ```
185+
186+ ** Text Parameters:**
187+
188+ - ` text ` : The string to render (required, cannot be empty)
189+ - ` size ` : Font size (default: 10)
190+ - ` height ` : Extrusion depth along Y-axis (default: 2)
191+ - ` curveSegments ` : Smoothness of curves (default: 12, lower=faster but blockier)
192+ - ` bevelEnabled ` : Add rounded edges to text (default: false)
193+ - ` color ` : Color of the text geometry
194+
195+ ** Important Notes:**
196+
197+ - Uses Helvetiker Regular font (built-in)
198+ - Text is automatically centered on XZ plane and aligned to Y=0
199+ - For engraving/embossing, make text height > target depth to ensure complete cut
200+ - ** Performance warning:** Long text (>10 characters) or high curveSegments can slow CSG operations
201+ - For better performance with long text, reduce ` curveSegments ` to 8
202+
203+ ### Rounded Box
204+
205+ Create boxes with filleted/rounded edges:
206+
207+ ``` typescript
208+ // Basic rounded box with auto-calculated radius (10% of smallest dimension)
209+ const box = Solid .roundedBox (10 , 10 , 10 , { color: ' teal' });
210+
211+ // Custom radius
212+ const customBox = Solid .roundedBox (20 , 15 , 10 , { color: ' blue' , radius: 2 });
213+
214+ // High quality rounding (more segments)
215+ const smoothBox = Solid .roundedBox (10 , 10 , 10 , { color: ' red' , radius: 1.5 , segments: 4 });
216+ ```
217+
218+ ** Rounded Box Parameters:**
219+
220+ - ` width ` , ` height ` , ` depth ` : Box dimensions (required, must be positive)
221+ - ` radius ` : Corner radius (default: 10% of smallest dimension)
222+ - Must be ≤ half of smallest dimension
223+ - Larger radius = more rounded corners
224+ - ` segments ` : Rounding quality (default: 2)
225+ - Higher values = smoother but more geometry
226+ - 2 is sufficient for most cases
227+
228+ ** Use Cases:**
229+
230+ - Mechanical parts with filleted edges
231+ - Product design and prototyping
232+ - Realistic objects (boxes are rarely sharp-edged in real life)
233+ - Ergonomic designs
234+
162235## Import Capabilities
163236
164237### STL Import
@@ -295,6 +368,67 @@ Solid.GRID_XY(brick, { cols: 10, rows: 5, spacing: [1, 0.5] }); // 2D
295368Solid .GRID_XYZ (brick , { cols: 5 , rows: 5 , levels: 3 , spacing: [1 , 1 , 2 ] }); // 3D
296369```
297370
371+ ### Circular Arrays
372+
373+ Arrange solids in circular/radial patterns (polar arrays):
374+
375+ ``` typescript
376+ // Gear teeth - elements face outward by default
377+ // IMPORTANT: Element must extend in +X direction to face outward when rotated
378+ // Width (X) > depth (Z) makes tooth point radially
379+ const disk = Solid .cylinder (15 , 8 , { color: ' gray' }).align (' bottom' );
380+ const tooth = Solid .cube (3 , 10 , 2 , { color: ' gray' }) // 3 wide (X), 2 deep (Z)
381+ .center ({ x: true , z: true })
382+ .align (' bottom' )
383+ .move ({ y: 8 }); // Position on top of disk
384+ const teeth = Solid .ARRAY_CIRCULAR (tooth , { count: 24 , radius: 17 });
385+ const gear = Solid .UNION (disk , teeth );
386+
387+ // Bolt holes - no rotation needed for holes
388+ const hole = Solid .cylinder (2 , 10 , { color: ' blue' }).setNegative ();
389+ const pattern = Solid .ARRAY_CIRCULAR (hole , { count: 8 , radius: 20 , rotateElements: false });
390+
391+ // Half circle (amphitheater seating)
392+ const seat = Solid .cube (2 , 1 , 2 , { color: ' red' });
393+ const seating = Solid .ARRAY_CIRCULAR (seat , { count: 15 , radius: 25 , startAngle: 0 , endAngle: 180 });
394+
395+ // Wheel spokes from center (radius = 0, just rotation)
396+ const spoke = Solid .cube (1 , 20 , 2 , { color: ' silver' }).center ({ x: true , z: true });
397+ const spokes = Solid .ARRAY_CIRCULAR (spoke , { count: 12 , radius: 0 });
398+
399+ // Decorative rosette with multiple layers
400+ const orb = Solid .sphere (2 , { color: ' gold' });
401+ const innerRing = Solid .ARRAY_CIRCULAR (orb , { count: 8 , radius: 8 , rotateElements: false });
402+ const outerRing = Solid .ARRAY_CIRCULAR (orb , { count: 16 , radius: 15 , rotateElements: false });
403+ const rosette = Solid .UNION (innerRing , outerRing );
404+ ```
405+
406+ ** Parameters:**
407+
408+ - ` count ` : Number of copies (required, must be >= 1)
409+ - ` radius ` : Radius of circular arrangement (required, must be > 0)
410+ - ` startAngle ` : Starting angle in degrees (default: 0)
411+ - ` endAngle ` : Ending angle in degrees (default: 360)
412+ - ` rotateElements ` : Rotate elements to face outward (default: true)
413+
414+ ** Key Behaviors:**
415+
416+ - Elements distributed evenly in XZ plane (horizontal circle around Y-axis)
417+ - By default, elements rotate to face outward (like gear teeth)
418+ - Set ` rotateElements: false ` for spheres, holes, or decorative elements
419+ - Partial circles: use ` startAngle ` /` endAngle ` for arcs (e.g., 0° to 180° = half circle)
420+ - Elements evenly spaced within angular range (startAngle included, endAngle excluded for full circles)
421+ - ** Y position preserved** : Elements maintain their vertical (Y) position, allowing layered circular patterns
422+ - ** Element orientation** : For radial elements, create them so they extend in the +X direction. When rotated, they'll face outward correctly. Example: for a tooth pointing outward, use ` cube(3, 10, 2) ` not ` cube(2, 10, 3) ` - width > depth
423+ - ** IMPORTANT** : Center elements with ` .center({ x: true, z: true }) ` before passing to ARRAY_CIRCULAR. The ` radius ` parameter handles X/Z positioning, but you can use ` .move({ y }) ` for vertical placement
424+
425+ ** Common Use Cases:**
426+
427+ - Mechanical: Gear teeth, splines, bolt holes, heat sink fins
428+ - Architectural: Columns, amphitheater seating, circular windows
429+ - Decorative: Medallions, rosettes, clock markers, mandalas
430+ - Functional: Turbine blades, fan blades, ventilation slots, spokes
431+
298432## Performance - Caching
299433
300434``` typescript
@@ -325,7 +459,7 @@ const w3 = Wall(30); // Different params, new computation
325459
326460### Factory Methods
327461
328- ` cube(w,h,d,opts) ` , ` cylinder(r,h,opts) ` , ` sphere(r,opts) ` , ` cone(r,h,opts) ` , ` prism(sides,r,h,opts) ` , ` trianglePrism(r,h,opts) `
462+ ` cube(w,h,d,opts) ` , ` roundedBox(w,h,d,opts) ` , ` cylinder(r,h,opts) ` , ` sphere(r,opts) ` , ` cone(r,h,opts) ` , ` prism(sides,r,h,opts) ` , ` trianglePrism(r,h,opts) ` , ` text(text ,opts)`
329463
330464### Import Methods
331465
@@ -351,9 +485,9 @@ const w3 = Wall(30); // Different params, new computation
351485
352486` SUBTRACT(src,...others) ` , ` UNION(src,...others) ` , ` INTERSECT(a,b) ` , ` MERGE(solids[]) `
353487
354- ### Grids (static, immutable)
488+ ### Grids & Arrays (static, immutable)
355489
356- ` GRID_X(solid,{cols,spacing?}) ` , ` GRID_XY(solid,{cols,rows,spacing?}) ` , ` GRID_XYZ(solid,{cols,rows,levels,spacing?}) `
490+ ` GRID_X(solid,{cols,spacing?}) ` , ` GRID_XY(solid,{cols,rows,spacing?}) ` , ` GRID_XYZ(solid,{cols,rows,levels,spacing?}) ` , ` ARRAY_CIRCULAR(solid,{count,radius,startAngle?,endAngle?,rotateElements?}) `
357491
358492### Alignment (chainable)
359493
0 commit comments