onshape 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -0
- package/dist/api/assemblies.js +60 -0
- package/dist/api/client.js +37 -2
- package/dist/api/configurations.js +18 -0
- package/dist/api/documents.js +7 -0
- package/dist/api/drawings.js +28 -0
- package/dist/api/export.js +109 -0
- package/dist/api/metadata.js +25 -0
- package/dist/api/partstudio.js +37 -0
- package/dist/api/variables.js +29 -0
- package/dist/builders/advanced.js +372 -0
- package/dist/builders/modeling.js +92 -3
- package/dist/cli.js +541 -54
- package/package.json +2 -2
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Advanced feature builders for Onshape — fillet, chamfer, shell, draft, revolve,
|
|
3
|
+
// boolean, mirror, patterns, offset-plane, and assembly mate/connector/group.
|
|
4
|
+
// 1:1 port of onshape_cli/builders/advanced.py.
|
|
5
|
+
//
|
|
6
|
+
// Every builder emits the standard BTFeatureDefinitionCall-1406 envelope the
|
|
7
|
+
// POST .../features endpoint expects. Selection is query-string based so it
|
|
8
|
+
// survives topology changes; explicit deterministic IDs are also supported.
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.qBodyOfFeature = exports.qAllBodies = exports.qCircularEdges = exports.qEdgesOfFeature = exports.qAllEdges = void 0;
|
|
11
|
+
exports.featureCall = featureCall;
|
|
12
|
+
exports.pQuery = pQuery;
|
|
13
|
+
exports.pSketchRegion = pSketchRegion;
|
|
14
|
+
exports.pQuantity = pQuantity;
|
|
15
|
+
exports.pEnum = pEnum;
|
|
16
|
+
exports.pBool = pBool;
|
|
17
|
+
exports.buildFillet = buildFillet;
|
|
18
|
+
exports.buildChamfer = buildChamfer;
|
|
19
|
+
exports.buildShell = buildShell;
|
|
20
|
+
exports.buildDraft = buildDraft;
|
|
21
|
+
exports.buildRevolveAxis = buildRevolveAxis;
|
|
22
|
+
exports.buildBoolean = buildBoolean;
|
|
23
|
+
exports.buildMirror = buildMirror;
|
|
24
|
+
exports.buildLinearPattern = buildLinearPattern;
|
|
25
|
+
exports.buildCircularPattern = buildCircularPattern;
|
|
26
|
+
exports.buildOffsetPlaneSelect = buildOffsetPlaneSelect;
|
|
27
|
+
exports.buildAssemblyMate = buildAssemblyMate;
|
|
28
|
+
exports.buildAssemblyMateConnector = buildAssemblyMateConnector;
|
|
29
|
+
exports.buildAssemblyGroup = buildAssemblyGroup;
|
|
30
|
+
// --- Low-level parameter helpers -------------------------------------------
|
|
31
|
+
function featureCall(featureType, name, parameters, namespace = "") {
|
|
32
|
+
return {
|
|
33
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
34
|
+
feature: {
|
|
35
|
+
btType: "BTMFeature-134",
|
|
36
|
+
featureType,
|
|
37
|
+
name,
|
|
38
|
+
suppressed: false,
|
|
39
|
+
namespace,
|
|
40
|
+
parameters,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function pQuery(parameterId, opts = {}) {
|
|
45
|
+
const query = {
|
|
46
|
+
btType: "BTMIndividualQuery-138",
|
|
47
|
+
deterministicIds: opts.deterministicIds ?? [],
|
|
48
|
+
};
|
|
49
|
+
if (opts.queryString) {
|
|
50
|
+
query.queryStatement = null;
|
|
51
|
+
query.queryString = opts.queryString;
|
|
52
|
+
}
|
|
53
|
+
if (opts.featureId)
|
|
54
|
+
query.featureId = opts.featureId;
|
|
55
|
+
return {
|
|
56
|
+
btType: "BTMParameterQueryList-148",
|
|
57
|
+
queries: [query],
|
|
58
|
+
parameterId,
|
|
59
|
+
parameterName: "",
|
|
60
|
+
libraryRelationType: "NONE",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function pSketchRegion(parameterId, sketchFeatureId) {
|
|
64
|
+
return {
|
|
65
|
+
btType: "BTMParameterQueryList-148",
|
|
66
|
+
queries: [
|
|
67
|
+
{
|
|
68
|
+
btType: "BTMIndividualSketchRegionQuery-140",
|
|
69
|
+
queryStatement: null,
|
|
70
|
+
filterInnerLoops: true,
|
|
71
|
+
queryString: `query = qSketchRegion(id + "${sketchFeatureId}", true);`,
|
|
72
|
+
featureId: sketchFeatureId,
|
|
73
|
+
deterministicIds: [],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
parameterId,
|
|
77
|
+
parameterName: "",
|
|
78
|
+
libraryRelationType: "NONE",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function pQuantity(parameterId, value, units = "in", opts = {}) {
|
|
82
|
+
let expression;
|
|
83
|
+
if (opts.variable)
|
|
84
|
+
expression = `#${opts.variable}`;
|
|
85
|
+
else if (opts.isInteger)
|
|
86
|
+
expression = `${Math.trunc(value)}`;
|
|
87
|
+
else if (units)
|
|
88
|
+
expression = `${value} ${units}`;
|
|
89
|
+
else
|
|
90
|
+
expression = `${value}`;
|
|
91
|
+
return {
|
|
92
|
+
btType: "BTMParameterQuantity-147",
|
|
93
|
+
isInteger: opts.isInteger ?? false,
|
|
94
|
+
value,
|
|
95
|
+
units: "",
|
|
96
|
+
expression,
|
|
97
|
+
parameterId,
|
|
98
|
+
parameterName: "",
|
|
99
|
+
libraryRelationType: "NONE",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function pEnum(parameterId, enumName, value) {
|
|
103
|
+
return {
|
|
104
|
+
btType: "BTMParameterEnum-145",
|
|
105
|
+
namespace: "",
|
|
106
|
+
enumName,
|
|
107
|
+
value,
|
|
108
|
+
parameterId,
|
|
109
|
+
parameterName: "",
|
|
110
|
+
libraryRelationType: "NONE",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function pBool(parameterId, value) {
|
|
114
|
+
return {
|
|
115
|
+
btType: "BTMParameterBoolean-144",
|
|
116
|
+
value,
|
|
117
|
+
parameterId,
|
|
118
|
+
parameterName: "",
|
|
119
|
+
libraryRelationType: "NONE",
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// --- Reusable selection query strings --------------------------------------
|
|
123
|
+
const qAllEdges = () => "query = qOwnedByBody(qAllModifiableSolidBodies(), EntityType.EDGE);";
|
|
124
|
+
exports.qAllEdges = qAllEdges;
|
|
125
|
+
const qEdgesOfFeature = (featureId) => `query = qCreatedBy(makeId("${featureId}"), EntityType.EDGE);`;
|
|
126
|
+
exports.qEdgesOfFeature = qEdgesOfFeature;
|
|
127
|
+
const qCircularEdges = () => "query = qGeometry(qOwnedByBody(qAllModifiableSolidBodies(), EntityType.EDGE), GeometryType.CIRCLE);";
|
|
128
|
+
exports.qCircularEdges = qCircularEdges;
|
|
129
|
+
const qAllBodies = () => "query = qAllModifiableSolidBodies();";
|
|
130
|
+
exports.qAllBodies = qAllBodies;
|
|
131
|
+
const qBodyOfFeature = (featureId) => `query = qCreatedBy(makeId("${featureId}"), EntityType.BODY);`;
|
|
132
|
+
exports.qBodyOfFeature = qBodyOfFeature;
|
|
133
|
+
function resolveEntityQuery(parameterId, sel, entity = "EDGE") {
|
|
134
|
+
if (sel.edgeIds && sel.edgeIds.length)
|
|
135
|
+
return pQuery(parameterId, { deterministicIds: sel.edgeIds });
|
|
136
|
+
if (sel.queryString)
|
|
137
|
+
return pQuery(parameterId, { queryString: sel.queryString });
|
|
138
|
+
if (sel.featureId) {
|
|
139
|
+
const qs = entity === "EDGE" ? (0, exports.qEdgesOfFeature)(sel.featureId) : (0, exports.qBodyOfFeature)(sel.featureId);
|
|
140
|
+
return pQuery(parameterId, { queryString: qs });
|
|
141
|
+
}
|
|
142
|
+
if (sel.circular)
|
|
143
|
+
return pQuery(parameterId, { queryString: (0, exports.qCircularEdges)() });
|
|
144
|
+
if (sel.selectAll)
|
|
145
|
+
return pQuery(parameterId, { queryString: (0, exports.qAllEdges)() });
|
|
146
|
+
throw new Error("No selection: pass edges, query, feature, --all, or --circular");
|
|
147
|
+
}
|
|
148
|
+
// --- Feature builders ------------------------------------------------------
|
|
149
|
+
function buildFillet(opts) {
|
|
150
|
+
const entities = resolveEntityQuery("entities", opts);
|
|
151
|
+
return featureCall("fillet", opts.name ?? "Fillet", [
|
|
152
|
+
entities,
|
|
153
|
+
pQuantity("radius", opts.radius ?? 0.1, "in", { variable: opts.radiusVariable }),
|
|
154
|
+
pEnum("filletType", "FilletType", opts.filletType ?? "EDGE"),
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
function buildChamfer(opts) {
|
|
158
|
+
const entities = resolveEntityQuery("entities", opts);
|
|
159
|
+
const chamferType = opts.chamferType ?? "EQUAL_OFFSETS";
|
|
160
|
+
const params = [
|
|
161
|
+
entities,
|
|
162
|
+
pEnum("chamferType", "ChamferType", chamferType),
|
|
163
|
+
pQuantity("width", opts.width ?? 0.1, "in", { variable: opts.widthVariable }),
|
|
164
|
+
];
|
|
165
|
+
if (chamferType === "OFFSET_ANGLE" && opts.angle !== undefined) {
|
|
166
|
+
params.push(pQuantity("angle", opts.angle, "deg"));
|
|
167
|
+
}
|
|
168
|
+
return featureCall("chamfer", opts.name ?? "Chamfer", params);
|
|
169
|
+
}
|
|
170
|
+
function buildShell(opts) {
|
|
171
|
+
let entities;
|
|
172
|
+
if (opts.faceIds && opts.faceIds.length)
|
|
173
|
+
entities = pQuery("entities", { deterministicIds: opts.faceIds });
|
|
174
|
+
else if (opts.queryString)
|
|
175
|
+
entities = pQuery("entities", { queryString: opts.queryString });
|
|
176
|
+
else
|
|
177
|
+
entities = pQuery("entities", { deterministicIds: [] });
|
|
178
|
+
const inward = opts.inward ?? true;
|
|
179
|
+
return featureCall("shell", opts.name ?? "Shell", [
|
|
180
|
+
entities,
|
|
181
|
+
pQuantity("thickness", opts.thickness ?? 0.125, "in", { variable: opts.thicknessVariable }),
|
|
182
|
+
pBool("oppositeDirection", !inward),
|
|
183
|
+
]);
|
|
184
|
+
}
|
|
185
|
+
function buildDraft(opts) {
|
|
186
|
+
return featureCall("draft", opts.name ?? "Draft", [
|
|
187
|
+
pQuery("neutralPlane", { queryString: opts.neutralPlaneQuery }),
|
|
188
|
+
pQuery("draftFaces", { queryString: opts.faceQuery }),
|
|
189
|
+
pQuantity("angle", opts.angle ?? 3.0, "deg"),
|
|
190
|
+
pBool("oppositeDirection", false),
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
function buildRevolveAxis(opts) {
|
|
194
|
+
const axis = opts.axisIds && opts.axisIds.length
|
|
195
|
+
? pQuery("axis", { deterministicIds: opts.axisIds })
|
|
196
|
+
: pQuery("axis", { queryString: opts.axisQuery });
|
|
197
|
+
const full = (opts.revolveType ?? "FULL") === "FULL";
|
|
198
|
+
const params = [
|
|
199
|
+
pEnum("bodyType", "ExtendedToolBodyType", "SOLID"),
|
|
200
|
+
pEnum("operationType", "NewBodyOperationType", opts.operationType ?? "NEW"),
|
|
201
|
+
pSketchRegion("entities", opts.sketchFeatureId),
|
|
202
|
+
axis,
|
|
203
|
+
pBool("fullRevolve", full),
|
|
204
|
+
];
|
|
205
|
+
if (!full) {
|
|
206
|
+
params.push(pEnum("endBound", "RevolveBoundingType", "BLIND"));
|
|
207
|
+
params.push(pQuantity("angle", opts.angle ?? 360.0, "deg"));
|
|
208
|
+
}
|
|
209
|
+
params.push(pBool("defaultScope", true));
|
|
210
|
+
return featureCall("revolve", opts.name ?? "Revolve", params);
|
|
211
|
+
}
|
|
212
|
+
function buildBoolean(opts) {
|
|
213
|
+
const operationType = opts.operationType ?? "UNION";
|
|
214
|
+
let tools;
|
|
215
|
+
if (opts.toolIds && opts.toolIds.length)
|
|
216
|
+
tools = pQuery("tools", { deterministicIds: opts.toolIds });
|
|
217
|
+
else if (opts.toolsQuery)
|
|
218
|
+
tools = pQuery("tools", { queryString: opts.toolsQuery });
|
|
219
|
+
else
|
|
220
|
+
tools = pQuery("tools", { queryString: (0, exports.qAllBodies)() });
|
|
221
|
+
const params = [
|
|
222
|
+
pEnum("operationType", "BooleanOperationType", operationType),
|
|
223
|
+
pBool("defaultScope", false),
|
|
224
|
+
tools,
|
|
225
|
+
pBool("toolsExplicit", true),
|
|
226
|
+
];
|
|
227
|
+
if (operationType === "SUBTRACTION") {
|
|
228
|
+
params.push(pBool("targetsAndToolsNeedGrouping", false));
|
|
229
|
+
if (opts.targetsQuery)
|
|
230
|
+
params.push(pQuery("targets", { queryString: opts.targetsQuery }));
|
|
231
|
+
}
|
|
232
|
+
return featureCall("booleanBodies", opts.name ?? "Boolean", params);
|
|
233
|
+
}
|
|
234
|
+
function buildMirror(opts) {
|
|
235
|
+
let plane;
|
|
236
|
+
if (opts.mirrorPlaneIds && opts.mirrorPlaneIds.length)
|
|
237
|
+
plane = pQuery("mirrorPlane", { deterministicIds: opts.mirrorPlaneIds });
|
|
238
|
+
else if (opts.mirrorPlaneQuery)
|
|
239
|
+
plane = pQuery("mirrorPlane", { queryString: opts.mirrorPlaneQuery });
|
|
240
|
+
else
|
|
241
|
+
throw new Error("Provide --plane-ids or --plane-query");
|
|
242
|
+
return featureCall("mirror", opts.name ?? "Mirror", [
|
|
243
|
+
pEnum("patternType", "MirrorType", opts.patternType ?? "PART"),
|
|
244
|
+
pEnum("operationType", "NewBodyOperationType", "NEW"),
|
|
245
|
+
pQuery("entities", { queryString: opts.entitiesQuery }),
|
|
246
|
+
plane,
|
|
247
|
+
]);
|
|
248
|
+
}
|
|
249
|
+
function buildLinearPattern(opts) {
|
|
250
|
+
const direction = opts.directionIds && opts.directionIds.length
|
|
251
|
+
? pQuery("directionOne", { deterministicIds: opts.directionIds })
|
|
252
|
+
: pQuery("directionOne", { queryString: opts.directionQuery });
|
|
253
|
+
return featureCall("linearPattern", opts.name ?? "Linear Pattern", [
|
|
254
|
+
pEnum("patternType", "PatternType", opts.patternType ?? "PART"),
|
|
255
|
+
pEnum("operationType", "NewBodyOperationType", "NEW"),
|
|
256
|
+
pQuery("entities", { queryString: opts.entitiesQuery }),
|
|
257
|
+
direction,
|
|
258
|
+
pBool("oppositeDirection", opts.opposite ?? false),
|
|
259
|
+
pQuantity("distance", opts.distance),
|
|
260
|
+
pQuantity("instanceCount", opts.instanceCount, "", { isInteger: true }),
|
|
261
|
+
pBool("hasSecondDir", false),
|
|
262
|
+
]);
|
|
263
|
+
}
|
|
264
|
+
function buildCircularPattern(opts) {
|
|
265
|
+
const axis = opts.axisIds && opts.axisIds.length
|
|
266
|
+
? pQuery("axis", { deterministicIds: opts.axisIds })
|
|
267
|
+
: pQuery("axis", { queryString: opts.axisQuery });
|
|
268
|
+
return featureCall("circularPattern", opts.name ?? "Circular Pattern", [
|
|
269
|
+
pEnum("patternType", "PatternType", opts.patternType ?? "PART"),
|
|
270
|
+
pEnum("operationType", "NewBodyOperationType", "NEW"),
|
|
271
|
+
pQuery("entities", { queryString: opts.entitiesQuery }),
|
|
272
|
+
axis,
|
|
273
|
+
pQuantity("angle", opts.angle ?? 360.0, "deg"),
|
|
274
|
+
pQuantity("instanceCount", opts.instanceCount, "", { isInteger: true }),
|
|
275
|
+
pBool("equalSpace", opts.equalSpacing ?? true),
|
|
276
|
+
]);
|
|
277
|
+
}
|
|
278
|
+
function buildOffsetPlaneSelect(opts) {
|
|
279
|
+
let base;
|
|
280
|
+
if (opts.basePlaneIds && opts.basePlaneIds.length)
|
|
281
|
+
base = pQuery("entities", { deterministicIds: opts.basePlaneIds });
|
|
282
|
+
else if (opts.basePlaneQuery)
|
|
283
|
+
base = pQuery("entities", { queryString: opts.basePlaneQuery });
|
|
284
|
+
else
|
|
285
|
+
base = pQuery("entities", { deterministicIds: ["JCC"] }); // Front
|
|
286
|
+
return featureCall("cPlane", opts.name ?? "Plane", [
|
|
287
|
+
pEnum("cplaneType", "CPlaneType", "OFFSET"),
|
|
288
|
+
base,
|
|
289
|
+
pQuantity("offset", opts.offset ?? 1.0),
|
|
290
|
+
pBool("oppositeDirection", false),
|
|
291
|
+
]);
|
|
292
|
+
}
|
|
293
|
+
// --- Assembly feature builders (posted to the assembly /features endpoint) --
|
|
294
|
+
function buildAssemblyMate(opts) {
|
|
295
|
+
const queries = opts.mateConnectorIds.map((fid) => ({
|
|
296
|
+
btType: "BTMFeatureQueryWithOccurrence-157",
|
|
297
|
+
path: [],
|
|
298
|
+
featureId: fid,
|
|
299
|
+
queryData: "",
|
|
300
|
+
}));
|
|
301
|
+
return {
|
|
302
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
303
|
+
feature: {
|
|
304
|
+
btType: "BTMMate-64",
|
|
305
|
+
featureType: "mate",
|
|
306
|
+
name: opts.name ?? "Mate",
|
|
307
|
+
suppressed: false,
|
|
308
|
+
parameters: [
|
|
309
|
+
pEnum("mateType", "Mate type", opts.mateType ?? "FASTENED"),
|
|
310
|
+
{
|
|
311
|
+
btType: "BTMParameterQueryWithOccurrenceList-67",
|
|
312
|
+
queries,
|
|
313
|
+
parameterId: "mateConnectorsQuery",
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function buildAssemblyMateConnector(opts) {
|
|
320
|
+
return {
|
|
321
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
322
|
+
feature: {
|
|
323
|
+
btType: "BTMMateConnector-66",
|
|
324
|
+
featureType: "mateConnector",
|
|
325
|
+
name: opts.name ?? "Mate connector",
|
|
326
|
+
suppressed: false,
|
|
327
|
+
parameters: [
|
|
328
|
+
{
|
|
329
|
+
btType: "BTMParameterEnum-145",
|
|
330
|
+
enumName: "Origin type",
|
|
331
|
+
value: "ON_ENTITY",
|
|
332
|
+
parameterId: "originType",
|
|
333
|
+
namespace: "",
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
btType: "BTMParameterQueryWithOccurrenceList-67",
|
|
337
|
+
parameterId: "originQuery",
|
|
338
|
+
queries: [
|
|
339
|
+
{
|
|
340
|
+
btType: "BTMInferenceQueryWithOccurrence-1083",
|
|
341
|
+
inferenceType: opts.inferenceType ?? "CENTROID",
|
|
342
|
+
path: [opts.occurrenceId],
|
|
343
|
+
deterministicIds: [],
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function buildAssemblyGroup(opts) {
|
|
352
|
+
const queries = opts.occurrenceIds.map((oid) => ({
|
|
353
|
+
btType: "BTMIndividualOccurrenceQuery-626",
|
|
354
|
+
path: [oid],
|
|
355
|
+
}));
|
|
356
|
+
return {
|
|
357
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
358
|
+
feature: {
|
|
359
|
+
btType: "BTMMateGroup-65",
|
|
360
|
+
featureType: "mateGroup",
|
|
361
|
+
name: opts.name ?? "Group",
|
|
362
|
+
suppressed: false,
|
|
363
|
+
parameters: [
|
|
364
|
+
{
|
|
365
|
+
btType: "BTMParameterQueryWithOccurrenceList-67",
|
|
366
|
+
queries,
|
|
367
|
+
parameterId: "occurrencesQuery",
|
|
368
|
+
},
|
|
369
|
+
],
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
}
|
|
@@ -6,6 +6,10 @@ exports.buildCircleSketch = buildCircleSketch;
|
|
|
6
6
|
exports.buildCircleAxisSketch = buildCircleAxisSketch;
|
|
7
7
|
exports.buildCandyCanePathSketch = buildCandyCanePathSketch;
|
|
8
8
|
exports.buildExtrude = buildExtrude;
|
|
9
|
+
exports.buildThicken = buildThicken;
|
|
10
|
+
exports.buildSketchFromEntities = buildSketchFromEntities;
|
|
11
|
+
exports.buildRectangleSketch = buildRectangleSketch;
|
|
12
|
+
exports.buildLineSketch = buildLineSketch;
|
|
9
13
|
exports.buildRevolve = buildRevolve;
|
|
10
14
|
exports.buildOffsetPlane = buildOffsetPlane;
|
|
11
15
|
exports.buildSweep = buildSweep;
|
|
@@ -32,7 +36,7 @@ function parsePoint2(value) {
|
|
|
32
36
|
function toMeters(value) {
|
|
33
37
|
return value * INCH_TO_METER;
|
|
34
38
|
}
|
|
35
|
-
function circleEntity(id, center, radius) {
|
|
39
|
+
function circleEntity(id, center, radius, isConstruction = false) {
|
|
36
40
|
return {
|
|
37
41
|
btType: "BTMSketchCurve-4",
|
|
38
42
|
entityId: id,
|
|
@@ -46,9 +50,24 @@ function circleEntity(id, center, radius) {
|
|
|
46
50
|
yDir: 0,
|
|
47
51
|
clockwise: false,
|
|
48
52
|
},
|
|
49
|
-
isConstruction
|
|
53
|
+
isConstruction,
|
|
50
54
|
};
|
|
51
55
|
}
|
|
56
|
+
function rectangleEntities(prefix, corner1, corner2) {
|
|
57
|
+
const [x1, y1] = corner1;
|
|
58
|
+
const [x2, y2] = corner2;
|
|
59
|
+
const corners = [
|
|
60
|
+
[x1, y1],
|
|
61
|
+
[x2, y1],
|
|
62
|
+
[x2, y2],
|
|
63
|
+
[x1, y2],
|
|
64
|
+
];
|
|
65
|
+
const segments = [];
|
|
66
|
+
for (let i = 0; i < 4; i += 1) {
|
|
67
|
+
segments.push(lineEntity(`${prefix}.${i}`, corners[i], corners[(i + 1) % 4]));
|
|
68
|
+
}
|
|
69
|
+
return segments;
|
|
70
|
+
}
|
|
52
71
|
function lineEntity(id, start, end, isConstruction = false) {
|
|
53
72
|
const x1 = toMeters(start[0]);
|
|
54
73
|
const y1 = toMeters(start[1]);
|
|
@@ -236,6 +255,20 @@ function buildCandyCanePathSketch(input) {
|
|
|
236
255
|
}
|
|
237
256
|
return sketch(input.name, planeId(input.plane), entities);
|
|
238
257
|
}
|
|
258
|
+
function depthQuantity(parameterId, value, variable) {
|
|
259
|
+
if (!variable)
|
|
260
|
+
return pQuantity(parameterId, value, "in");
|
|
261
|
+
return {
|
|
262
|
+
btType: "BTMParameterQuantity-147",
|
|
263
|
+
isInteger: false,
|
|
264
|
+
value,
|
|
265
|
+
units: "",
|
|
266
|
+
expression: `#${variable}`,
|
|
267
|
+
parameterId,
|
|
268
|
+
parameterName: "",
|
|
269
|
+
libraryRelationType: "NONE",
|
|
270
|
+
};
|
|
271
|
+
}
|
|
239
272
|
function buildExtrude(input) {
|
|
240
273
|
return {
|
|
241
274
|
btType: "BTFeatureDefinitionCall-1406",
|
|
@@ -248,13 +281,69 @@ function buildExtrude(input) {
|
|
|
248
281
|
parameters: [
|
|
249
282
|
sketchRegion("entities", input.sketchFeatureId),
|
|
250
283
|
pEnum("operationType", "NewBodyOperationType", input.operationType),
|
|
251
|
-
|
|
284
|
+
depthQuantity("depth", input.depth, input.depthVariable),
|
|
252
285
|
pBool("oppositeDirection", false),
|
|
253
286
|
pBool("defaultScope", true),
|
|
254
287
|
],
|
|
255
288
|
},
|
|
256
289
|
};
|
|
257
290
|
}
|
|
291
|
+
/** thicken — mirrors onshape_cli/builders/thicken.py (bare BTMFeature-134). */
|
|
292
|
+
function buildThicken(input) {
|
|
293
|
+
const expression = input.thicknessVariable ? `#${input.thicknessVariable}` : `${input.thickness} in`;
|
|
294
|
+
return {
|
|
295
|
+
btType: "BTMFeature-134",
|
|
296
|
+
name: input.name,
|
|
297
|
+
suppressed: false,
|
|
298
|
+
namespace: "",
|
|
299
|
+
featureType: "thicken",
|
|
300
|
+
parameters: [
|
|
301
|
+
{ btType: "BTMParameterEnum-145", enumName: "NewBodyOperationType", value: input.operationType, parameterId: "operationType" },
|
|
302
|
+
sketchRegion("entities", input.sketchFeatureId),
|
|
303
|
+
{ btType: "BTMParameterBoolean-144", value: input.midplane ?? false, parameterId: "midplane" },
|
|
304
|
+
{ btType: "BTMParameterQuantity-147", expression, parameterId: "thickness1" },
|
|
305
|
+
{ btType: "BTMParameterBoolean-144", value: input.opposite ?? false, parameterId: "oppositeDirection" },
|
|
306
|
+
{ btType: "BTMParameterQuantity-147", expression: "0 in", parameterId: "thickness2" },
|
|
307
|
+
],
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/** Generic sketch from a parsed entity list (create-sketch). Matches the
|
|
311
|
+
* Python contract: types line/circle/rectangle (arc is not supported). */
|
|
312
|
+
function buildSketchFromEntities(input) {
|
|
313
|
+
const out = [];
|
|
314
|
+
input.entities.forEach((entity, index) => {
|
|
315
|
+
const type = String(entity.type ?? "");
|
|
316
|
+
const construction = Boolean(entity.construction);
|
|
317
|
+
if (type === "line") {
|
|
318
|
+
out.push(lineEntity(`e${index}`, point(entity.start), point(entity.end), construction));
|
|
319
|
+
}
|
|
320
|
+
else if (type === "circle") {
|
|
321
|
+
out.push(circleEntity(`e${index}`, point(entity.center), Number(entity.radius), construction));
|
|
322
|
+
}
|
|
323
|
+
else if (type === "rectangle") {
|
|
324
|
+
out.push(...rectangleEntities(`e${index}`, point(entity.corner1), point(entity.corner2)));
|
|
325
|
+
}
|
|
326
|
+
else if (type === "arc") {
|
|
327
|
+
throw new Error("arc entities not supported by this sketch builder yet; use line/circle/rectangle");
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
throw new Error(`Unknown sketch entity type '${type}'. Use line, circle, or rectangle.`);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
return sketch(input.name, planeId(input.plane), out);
|
|
334
|
+
}
|
|
335
|
+
function buildRectangleSketch(input) {
|
|
336
|
+
return sketch(input.name, planeId(input.plane), rectangleEntities("rect", input.corner1, input.corner2));
|
|
337
|
+
}
|
|
338
|
+
function buildLineSketch(input) {
|
|
339
|
+
return sketch(input.name, planeId(input.plane), [lineEntity("line.1", input.start, input.end)]);
|
|
340
|
+
}
|
|
341
|
+
function point(value) {
|
|
342
|
+
if (Array.isArray(value) && value.length === 2 && value.every((v) => Number.isFinite(Number(v)))) {
|
|
343
|
+
return [Number(value[0]), Number(value[1])];
|
|
344
|
+
}
|
|
345
|
+
throw new Error(`Expected a [x, y] point; got ${JSON.stringify(value)}`);
|
|
346
|
+
}
|
|
258
347
|
function buildRevolve(input) {
|
|
259
348
|
return {
|
|
260
349
|
btType: "BTFeatureDefinitionCall-1406",
|