0
# Expansions and Modifications
1
2
All shapes (primitives or the results of operations) can be expanded, contracted, or modified to correct issues and improve geometry quality. In all cases, these functions return new results and never change the original geometry.
3
4
## Expansions
5
6
### Expand
7
8
Expand shapes by adding material uniformly around their perimeter or surface.
9
10
```javascript { .api }
11
/**
12
* Expand geometries by adding material around the perimeter/surface
13
* @param {Object} options - Expansion options
14
* @param {Number} options.delta - Distance to expand (positive) or contract (negative)
15
* @param {String} [options.corners='round'] - Corner style: 'round', 'chamfer', or 'square'
16
* @param {Number} [options.segments=16] - Number of segments for rounded corners
17
* @param {...Object} objects - Objects to expand
18
* @returns {Object|Array} Expanded object(s)
19
*/
20
function expand(options: {
21
delta: number,
22
corners?: 'round' | 'chamfer' | 'square',
23
segments?: number
24
}, ...objects: any[]): any;
25
```
26
27
**Usage Examples:**
28
29
```javascript
30
const { rectangle, cube, expand } = require('@jscad/modeling');
31
32
// Expand 2D shape with rounded corners
33
const rect = rectangle({ size: [10, 6] });
34
const expandedRect = expand({ delta: 2, corners: 'round' }, rect);
35
36
// Contract 3D shape (negative delta)
37
const myCube = cube({ size: 10 });
38
const contractedCube = expand({ delta: -1 }, myCube);
39
40
// Expand with chamfered corners
41
const chamferedExpansion = expand({
42
delta: 1.5,
43
corners: 'chamfer',
44
segments: 8
45
}, rect);
46
```
47
48
### Offset
49
50
Create 2D offset curves from 2D shapes, useful for creating tool paths and margin operations.
51
52
```javascript { .api }
53
/**
54
* Create offset curves from 2D shapes
55
* @param {Object} options - Offset options
56
* @param {Number} options.delta - Distance to offset (positive for outward, negative for inward)
57
* @param {String} [options.corners='round'] - Corner style: 'round', 'chamfer', or 'square'
58
* @param {Number} [options.segments=16] - Number of segments for rounded corners
59
* @param {...Object} objects - 2D objects to offset (geom2)
60
* @returns {geom2|Array} Offset 2D geometries
61
*/
62
function offset(options: {
63
delta: number,
64
corners?: 'round' | 'chamfer' | 'square',
65
segments?: number
66
}, ...objects: geom2[]): geom2 | geom2[];
67
```
68
69
**Usage Examples:**
70
71
```javascript
72
const { circle, polygon, offset, union } = require('@jscad/modeling');
73
74
// Create tool path offset
75
const partOutline = polygon({
76
points: [[0, 0], [10, 0], [10, 8], [5, 12], [0, 8]]
77
});
78
const toolPath = offset({ delta: 3, corners: 'round' }, partOutline);
79
80
// Create multiple offset rings
81
const baseCircle = circle({ radius: 5 });
82
const offsets = [];
83
for (let i = 1; i <= 5; i++) {
84
offsets.push(offset({ delta: i * 2 }, baseCircle));
85
}
86
const concentricRings = union(...offsets);
87
```
88
89
## Modifiers
90
91
### Snap
92
93
Snap vertices to a grid or custom function to clean up geometry and reduce precision errors.
94
95
```javascript { .api }
96
/**
97
* Snap vertices of geometries to a grid or custom function
98
* @param {Object} options - Snap options
99
* @param {Function} options.snapFunction - Function that snaps a vertex: (vertex) => snappedVertex
100
* @param {...Object} objects - Objects to snap
101
* @returns {Object|Array} Objects with snapped vertices
102
*/
103
function snap(options: {
104
snapFunction: (vertex: [number, number, number]) => [number, number, number]
105
}, ...objects: any[]): any;
106
```
107
108
**Usage Examples:**
109
110
```javascript
111
const { cube, sphere, snap, union } = require('@jscad/modeling');
112
113
// Snap to 0.1 unit grid
114
const gridSnap = (vertex) => [
115
Math.round(vertex[0] * 10) / 10,
116
Math.round(vertex[1] * 10) / 10,
117
Math.round(vertex[2] * 10) / 10
118
];
119
120
const roughShape = union(
121
cube({ size: 10.0123 }),
122
sphere({ radius: 4.9876 })
123
);
124
const cleanShape = snap({ snapFunction: gridSnap }, roughShape);
125
126
// Snap to custom positions
127
const customSnap = (vertex) => {
128
// Snap to nearest multiple of 5
129
return [
130
Math.round(vertex[0] / 5) * 5,
131
Math.round(vertex[1] / 5) * 5,
132
Math.round(vertex[2] / 5) * 5
133
];
134
};
135
const customSnapped = snap({ snapFunction: customSnap }, roughShape);
136
```
137
138
### Retessellate
139
140
Retessellate meshes to improve triangle quality and reduce complexity.
141
142
```javascript { .api }
143
/**
144
* Retessellate geometries to improve mesh quality
145
* @param {Object} options - Retessellation options
146
* @param {Number} [options.maxAngle=Math.PI] - Maximum angle between face normals for coplanar detection
147
* @param {...Object} objects - Objects to retessellate
148
* @returns {Object|Array} Retessellated objects
149
*/
150
function retessellate(options?: {
151
maxAngle?: number
152
}, ...objects: any[]): any;
153
```
154
155
**Usage Examples:**
156
157
```javascript
158
const { sphere, cube, union, retessellate } = require('@jscad/modeling');
159
160
// Retessellate complex boolean result
161
const complex = union(
162
sphere({ radius: 5, segments: 64 }),
163
cube({ size: 8 }),
164
sphere({ radius: 3, center: [4, 4, 4] })
165
);
166
const optimized = retessellate({}, complex);
167
168
// Retessellate with custom angle threshold
169
const strictRetessellation = retessellate({
170
maxAngle: Math.PI / 6 // 30 degrees
171
}, complex);
172
```
173
174
### Generalize
175
176
Convert specific geometry types to more general forms for compatibility and processing.
177
178
```javascript { .api }
179
/**
180
* Generalize geometries to more general forms
181
* @param {Object} options - Generalization options
182
* @param {Boolean} [options.snap=true] - Whether to snap vertices during generalization
183
* @param {Number} [options.snapFunction] - Custom snap function
184
* @param {...Object} objects - Objects to generalize
185
* @returns {Object|Array} Generalized objects
186
*/
187
function generalize(options?: {
188
snap?: boolean,
189
snapFunction?: (vertex: [number, number, number]) => [number, number, number]
190
}, ...objects: any[]): any;
191
```
192
193
**Usage Examples:**
194
195
```javascript
196
const { path2, polygon, generalize } = require('@jscad/modeling');
197
198
// Convert path2 to geom2 for boolean operations
199
const myPath = path2.fromPoints([[0, 0], [5, 0], [5, 5], [0, 5], [0, 0]]);
200
const generalizedShape = generalize({}, myPath);
201
202
// Generalize with custom snapping
203
const preciseGeneralize = generalize({
204
snap: true,
205
snapFunction: (v) => [Math.round(v[0]), Math.round(v[1]), Math.round(v[2])]
206
}, myPath);
207
```
208
209
## Hull Operations
210
211
Hull operations compute convex boundaries around sets of shapes or points.
212
213
### Hull
214
215
Create the convex hull of multiple shapes, enclosing all input geometry.
216
217
```javascript { .api }
218
/**
219
* Create convex hull of shapes
220
* @param {...Object} objects - Objects to hull
221
* @returns {Object} Convex hull containing all input objects
222
*/
223
function hull(...objects: any[]): any;
224
```
225
226
### Hull Chain
227
228
Create a chain of hulls between consecutive shapes, useful for creating smooth transitions.
229
230
```javascript { .api }
231
/**
232
* Create chain of hulls between consecutive shapes
233
* @param {...Object} objects - Objects to chain with hulls
234
* @returns {Object} Union of hulls between consecutive pairs
235
*/
236
function hullChain(...objects: any[]): any;
237
```
238
239
### Point-based Hulls
240
241
Create hulls directly from point sets.
242
243
```javascript { .api }
244
/**
245
* Create 2D convex hull from points
246
* @param {Array} points - Array of [x,y] points
247
* @returns {geom2} 2D convex hull geometry
248
*/
249
function hullPoints2(points: Array<[number, number]>): geom2;
250
251
/**
252
* Create 3D convex hull from points
253
* @param {Array} points - Array of [x,y,z] points
254
* @returns {geom3} 3D convex hull geometry
255
*/
256
function hullPoints3(points: Array<[number, number, number]>): geom3;
257
```
258
259
**Usage Examples:**
260
261
```javascript
262
const { cube, sphere, cylinder, hull, hullChain, hullPoints3, translate } = require('@jscad/modeling');
263
264
// Hull multiple shapes
265
const shape1 = cube({ size: 5 });
266
const shape2 = translate([10, 0, 0], sphere({ radius: 3 }));
267
const shape3 = translate([5, 8, 0], cylinder({ height: 6, radius: 2 }));
268
const hullResult = hull(shape1, shape2, shape3);
269
270
// Create smooth chain between shapes
271
const smoothTransition = hullChain(shape1, shape2, shape3);
272
273
// Hull from point cloud
274
const points = [
275
[0, 0, 0], [5, 0, 0], [2.5, 4, 0], [2.5, 2, 6], [1, 1, 8]
276
];
277
const pointHull = hullPoints3(points);
278
```
279
280
## Advanced Techniques
281
282
### Combining Operations
283
284
Complex modifications often combine multiple operations:
285
286
```javascript
287
const { rectangle, expand, offset, snap, union } = require('@jscad/modeling');
288
289
// Create a part with precise dimensions and clean geometry
290
const baseRect = rectangle({ size: [20, 15] });
291
292
// Add material and create offsets
293
const expanded = expand({ delta: 2, corners: 'round' }, baseRect);
294
const innerOffset = offset({ delta: -1 }, baseRect);
295
296
// Combine and clean up
297
const combined = union(expanded, innerOffset);
298
const cleanFinal = snap({
299
snapFunction: (v) => [Math.round(v[0] * 100) / 100, Math.round(v[1] * 100) / 100]
300
}, combined);
301
```
302
303
### Manufacturing Considerations
304
305
Use expansions and modifications for manufacturing preparation:
306
307
```javascript
308
const { cube, expand, retessellate } = require('@jscad/modeling');
309
310
// Add material allowance for machining
311
const rawPart = expand({ delta: 0.5 }, cube({ size: 10 }));
312
313
// Optimize mesh for 3D printing
314
const printReady = retessellate({ maxAngle: Math.PI / 4 }, rawPart);
315
316
// Create tool clearance
317
const toolClearance = expand({ delta: 1.5, corners: 'round' }, printReady);
318
```
319
320
### Performance Tips
321
322
- Use retessellate after complex boolean operations to improve mesh quality
323
- Apply snap operations to reduce floating-point precision issues
324
- Consider expand with negative delta as an alternative to complex subtract operations
325
- Hull operations can be computationally expensive with many input shapes