Skip to content

Commit 1a6beec

Browse files
Update KCL docs (#1063)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent a221313 commit 1a6beec

34 files changed

Lines changed: 574 additions & 475 deletions

File tree

-36 KB
Loading
-35 KB
Loading
1.93 KB
Loading
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
title: "Face API Edge References"
3+
excerpt: "Identifying edges by their surrounding faces in KCL."
4+
layout: manual
5+
---
6+
7+
The face API identifies an edge from the faces around it instead of relying on
8+
the edge's position in a body's internal ordering. This makes references more
9+
stable when earlier modeling operations change the body's topology.
10+
11+
For most solid edges, the two adjacent faces uniquely identify the edge. Put
12+
those faces in `sideFaces`:
13+
14+
```kcl,norun
15+
fillet(
16+
body001,
17+
radius = 2,
18+
edges = [{
19+
sideFaces = [region001.tags.bottom, endCap]
20+
}],
21+
)
22+
```
23+
24+
The faces in `sideFaces` run along the length of the edge. An operation can
25+
split an edge into multiple edges that still have the same side faces. To select
26+
one split, add an `endFaces` entry for a face touching the end of the intended
27+
edge:
28+
29+
```kcl,norun
30+
{
31+
sideFaces = [region001.tags.bottom, region001.tags.right],
32+
endFaces = [startCap]
33+
}
34+
```
35+
36+
Some solid-modeling topology can leave multiple edges with the same side and
37+
end faces. In that case, `index` selects one of the remaining matches using a
38+
zero-based index:
39+
40+
```kcl,norun
41+
{
42+
sideFaces = [region001.tags.bottom, endCap],
43+
index = 1
44+
}
45+
```
46+
47+
Prefer `sideFaces` alone when it is unambiguous. Add `endFaces` when an edge has
48+
been split, and use `index` only when the face information still leaves more
49+
than one match. When a Face API selection supplies an edge-reference object,
50+
keep the fields it provides rather than converting the selection to legacy
51+
edge helpers.
52+
53+
An edge-reference object does not have to identify exactly one edge. A broader
54+
reference can intentionally match multiple edges so that an operation applies
55+
to all of them. Add `endFaces` or `index` only when the operation should target
56+
a smaller subset of those matches.
57+
58+
Surface bodies do not always provide two side faces or useful end faces. Their
59+
edge references can therefore contain a single `sideFaces` entry and rely on
60+
`index` more often to choose a boundary edge.
61+
62+
The same edge-reference object can be used by operations such as `fillet`,
63+
`chamfer`, `revolve`, `helix`, and `mirror3d` where their parameter accepts an
64+
edge.
65+
66+
Sketch segments remain direct references, such as `sketch001.line1`. Edge
67+
reference objects are for edges on generated bodies, where adjacent face tags
68+
provide a stable description of the intended geometry.
69+
70+
## Edges involving generated faces
71+
72+
Fillets and chamfers create new faces that can form part of edges used by later
73+
operations. Add `tag` to the edge-treatment operation to name its generated
74+
face, then use that tag in the later edge reference. The existing operation
75+
produces the face and should remain in the model; selecting one of its generated
76+
faces does not mean replacing the operation itself.
77+
78+
For example, this fillet targets the edge shared by the existing chamfer face
79+
and the extrusion's end cap:
80+
81+
```kcl,norun
82+
chamfer001 = chamfer(
83+
body001,
84+
edges = [{
85+
sideFaces = [region001.tags.right, region001.tags.bottom]
86+
}],
87+
length = 4,
88+
tag = $chamferFace,
89+
)
90+
91+
fillet001 = fillet(
92+
body001,
93+
edges = [{
94+
sideFaces = [chamferFace, endCap]
95+
}],
96+
radius = 2,
97+
)
98+
```

‎content/pages/docs/kcl-lang/index.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ things in a more tutorial fashion. See also our documentation of the [standard l
1818
* [Arrays and ranges](/docs/kcl-lang/arrays)
1919
* [Enums](/docs/kcl-lang/enums)
2020
* [Sketch on Face](/docs/kcl-lang/sketch-on-face)
21+
* [Edge references](/docs/kcl-lang/edge-references)
2122
* [Projects and modules](/docs/kcl-lang/modules)
2223
* [Attributes](/docs/kcl-lang/attributes)
2324
* [Python-to-KCL Cheat Sheet](/docs/kcl-lang/python-cheat-sheet)

‎content/pages/docs/kcl-samples/angle-gauge/main.kcl‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ gaugeProfileSketch = sketch(on = XY) {
4646
vertical(lowerRightOuterEdge)
4747

4848
horizontalDistance([
49-
bottomOuterEdge.end,
50-
bottomOuterEdge.start
51-
]) == gaugeDepth
49+
bottomOuterEdge.end,
50+
bottomOuterEdge.start
51+
]) == gaugeDepth
5252
verticalDistance([
53-
lowerRightOuterEdge.end,
54-
lowerRightOuterEdge.start
55-
]) == lowerCutoutStartY
53+
lowerRightOuterEdge.end,
54+
lowerRightOuterEdge.start
55+
]) == lowerCutoutStartY
5656

5757
// Angled cutout profile.
5858
cutoutAngledEdge = line(start = [var 1.5in, var 0.19in], end = [var 0.5in, var 0.37in])
@@ -89,18 +89,18 @@ gaugeProfileSketch = sketch(on = XY) {
8989
horizontal(cutoutAngleReferenceEdge)
9090
vertical(cutoutLeftVerticalEdge)
9191
angleDimension(
92-
lines = [
93-
cutoutAngleReferenceEdge,
94-
cutoutAngledEdge
95-
],
96-
sector = 1,
97-
) == cutoutAngle
92+
lines = [
93+
cutoutAngleReferenceEdge,
94+
cutoutAngledEdge
95+
],
96+
sector = 1,
97+
) == cutoutAngle
9898

9999
horizontalDistance([cutoutTopEdge.start, cutoutTopEdge.end]) == cutoutDepth
100100
verticalDistance([
101-
rightCutoutConstructionEdge.end,
102-
rightCutoutConstructionEdge.start
103-
]) == cutoutWidth
101+
rightCutoutConstructionEdge.end,
102+
rightCutoutConstructionEdge.start
103+
]) == cutoutWidth
104104
verticalDistance([leftOuterEdge.start, leftOuterEdge.end]) == gaugeWidth
105105
coincident([
106106
rightCutoutConstructionEdge.end,

‎content/pages/docs/kcl-samples/bracket-with-slot/main.kcl‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ tabHoleSketch = sketch(on = tabHolePlane) {
133133
])
134134
horizontal(countersinkGuide)
135135
horizontalDistance([
136-
countersinkGuide.start,
137-
countersinkGuide.end
138-
]) == countersinkOuterDiameter / 2
136+
countersinkGuide.start,
137+
countersinkGuide.end
138+
]) == countersinkOuterDiameter / 2
139139

140140
coincident([
141141
fastenerCircle.center,
@@ -246,9 +246,9 @@ slotProfile = sketch(on = XY) {
246246
vertical(rightBottomGuide)
247247

248248
horizontalDistance([
249-
slotCenterline.start,
250-
slotCenterline.end
251-
]) == slotOverallLength
249+
slotCenterline.start,
250+
slotCenterline.end
251+
]) == slotOverallLength
252252
radius(arc2) == slotWidth / 2
253253
radius(arc4) == slotWidth / 2
254254
coincident([

‎content/pages/docs/kcl-samples/ceiling-fan/main.kcl‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,23 +143,23 @@ bladeProfile = sketch(on = bladePlane) {
143143
verticalDistance([bladeAxisSpan.start, bladeAxisSpan.end]) == bladeSpanLength - bladeTipRadius
144144
verticalDistance([bladeAxisTip.start, bladeAxisTip.end]) == bladeTipRadius
145145
horizontalDistance([
146-
rootGuideRight.start,
147-
rootGuideRight.end
148-
]) == bladeRootHalfWidth
146+
rootGuideRight.start,
147+
rootGuideRight.end
148+
]) == bladeRootHalfWidth
149149
horizontalDistance([rootGuideLeft.start, rootGuideLeft.end]) == bladeRootHalfWidth
150150
horizontalDistance([
151-
neckGuideRight.start,
152-
neckGuideRight.end
153-
]) == bladeNeckHalfWidth
151+
neckGuideRight.start,
152+
neckGuideRight.end
153+
]) == bladeNeckHalfWidth
154154
horizontalDistance([neckGuideLeft.start, neckGuideLeft.end]) == bladeNeckHalfWidth
155155
horizontalDistance([
156-
tipCenterGuideRight.start,
157-
tipCenterGuideRight.end
158-
]) == bladeTipFlatHalfWidth
156+
tipCenterGuideRight.start,
157+
tipCenterGuideRight.end
158+
]) == bladeTipFlatHalfWidth
159159
horizontalDistance([
160-
tipCenterGuideLeft.start,
161-
tipCenterGuideLeft.end
162-
]) == bladeTipFlatHalfWidth
160+
tipCenterGuideLeft.start,
161+
tipCenterGuideLeft.end
162+
]) == bladeTipFlatHalfWidth
163163
}
164164

165165
// Step 2: extrude the solved blade blank.
@@ -199,9 +199,9 @@ voidProfile = sketch(on = YZ) {
199199
vertical(outerEdge)
200200
tangent([bottomEdge, innerArc])
201201
verticalDistance([
202-
baseOffsetGuide.start,
203-
baseOffsetGuide.end
204-
]) == voidCutoutBottomOffset
202+
baseOffsetGuide.start,
203+
baseOffsetGuide.end
204+
]) == voidCutoutBottomOffset
205205

206206
verticalDistance([arcRiseGuide.start, arcRiseGuide.end]) == voidCutoutHeight
207207
horizontalDistance([topEdge.start, topEdge.end]) == voidCutoutLength

‎content/pages/docs/kcl-samples/cold-plate/main.kcl‎

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -314,42 +314,42 @@ copperTubePath = sketch(on = offsetPlane(XY, offset = tubeDiameter)) {
314314
horizontalDistance([inletGuide.start, inletGuide.end]) == tubeInletX
315315
verticalDistance([inletGuide.start, inletGuide.end]) == tubeLowerPassY
316316
horizontalDistance([
317-
rightLowerLoopGuide.start,
318-
rightLowerLoopGuide.end
319-
]) == tubeRightLoopX
317+
rightLowerLoopGuide.start,
318+
rightLowerLoopGuide.end
319+
]) == tubeRightLoopX
320320
verticalDistance([
321-
rightLowerLoopGuide.start,
322-
rightLowerLoopGuide.end
323-
]) == tubeLowerLoopCenterY
321+
rightLowerLoopGuide.start,
322+
rightLowerLoopGuide.end
323+
]) == tubeLowerLoopCenterY
324324
horizontalDistance([leftLoopGuide.start, leftLoopGuide.end]) == tubeLeftLoopX
325325
verticalDistance([leftLoopGuide.start, leftLoopGuide.end]) == 0in
326326
horizontalDistance([
327-
rightUpperLoopGuide.start,
328-
rightUpperLoopGuide.end
329-
]) == tubeRightLoopX
327+
rightUpperLoopGuide.start,
328+
rightUpperLoopGuide.end
329+
]) == tubeRightLoopX
330330
verticalDistance([
331-
rightUpperLoopGuide.start,
332-
rightUpperLoopGuide.end
333-
]) == tubeUpperLoopCenterY
331+
rightUpperLoopGuide.start,
332+
rightUpperLoopGuide.end
333+
]) == tubeUpperLoopCenterY
334334
horizontalDistance([outletGuide.start, outletGuide.end]) == tubeInletX
335335
verticalDistance([outletGuide.start, outletGuide.end]) == tubeUpperPassY
336336
distance([
337-
rightLowerArcStartGuide.start,
338-
rightLowerArcStartGuide.end
339-
]) == bendRadius
337+
rightLowerArcStartGuide.start,
338+
rightLowerArcStartGuide.end
339+
]) == bendRadius
340340
equalLength([
341341
rightLowerArcStartGuide,
342342
rightLowerArcEndGuide
343343
])
344344
distance([
345-
leftArcStartGuide.start,
346-
leftArcStartGuide.end
347-
]) == bendRadius
345+
leftArcStartGuide.start,
346+
leftArcStartGuide.end
347+
]) == bendRadius
348348
equalLength([leftArcStartGuide, leftArcEndGuide])
349349
distance([
350-
rightUpperArcStartGuide.start,
351-
rightUpperArcStartGuide.end
352-
]) == bendRadius
350+
rightUpperArcStartGuide.start,
351+
rightUpperArcStartGuide.end
352+
]) == bendRadius
353353
equalLength([
354354
rightUpperArcStartGuide,
355355
rightUpperArcEndGuide
@@ -389,21 +389,21 @@ brazedCapProfile = sketch(on = YZ) {
389389
tangent([arc3, line4])
390390
vertical(line4)
391391
horizontalDistance([
392-
bottomCenterGuide.start,
393-
bottomCenterGuide.end
394-
]) == secondGrooveCenterY
392+
bottomCenterGuide.start,
393+
bottomCenterGuide.end
394+
]) == secondGrooveCenterY
395395
verticalDistance([
396-
bottomCenterGuide.start,
397-
bottomCenterGuide.end
398-
]) == grooveFloorZ
396+
bottomCenterGuide.start,
397+
bottomCenterGuide.end
398+
]) == grooveFloorZ
399399
horizontalDistance([
400-
topCenterGuide.start,
401-
topCenterGuide.end
402-
]) == secondGrooveCenterY
400+
topCenterGuide.start,
401+
topCenterGuide.end
402+
]) == secondGrooveCenterY
403403
verticalDistance([
404-
topCenterGuide.start,
405-
topCenterGuide.end
406-
]) == plateTopZ + tubeDiameter * 0.75
404+
topCenterGuide.start,
405+
topCenterGuide.end
406+
]) == plateTopZ + tubeDiameter * 0.75
407407
distance([line2.start, line2.end]) == grooveWallHeight
408408
equalLength([line2, line4])
409409
radius(arc3) == tubeOuterRadius
@@ -453,13 +453,13 @@ tubeSectionSketch = sketch(on = offsetPlane(YZ, offset = tubeInletX)) {
453453
horizontalDistance([centerGuide.start, centerGuide.end]) == tubeLowerPassY
454454
verticalDistance([centerGuide.start, centerGuide.end]) == grooveFloorZ
455455
horizontalDistance([
456-
outerRadiusGuide.start,
457-
outerRadiusGuide.end
458-
]) == tubeOuterRadius
456+
outerRadiusGuide.start,
457+
outerRadiusGuide.end
458+
]) == tubeOuterRadius
459459
horizontalDistance([
460-
innerRadiusGuide.start,
461-
innerRadiusGuide.end
462-
]) == tubeInnerRadius
460+
innerRadiusGuide.start,
461+
innerRadiusGuide.end
462+
]) == tubeInnerRadius
463463
}
464464

465465
tubeSectionProfile = region(segments = [tubeSectionSketch.outerCircle])

0 commit comments

Comments
 (0)