pub fn fillet_edges(
model: &mut Model,
solid: &Shape,
edges: &[Shape],
radius: f64,
tol: Tolerances,
) -> OgeomResult<Built>Expand description
Round a chain of edges in one call, each blend applied in turn and every later edge resolved through the history the earlier blends wrote.
A solid bounded by planes, each face one ring of straight edges, goes first through the blend engine (docs/adr/0001-blend-architecture.md), which builds the whole request in one pass, the same solid in any order. Every face is set back to where its rounds’ contact lines meet. Every round is its exact cylinder between them, ended through its faces’ setback corners (skew on the cylinder where they stand at different stations). A vertex closes as a sphere where one ball touches its three faces there, flush in its third face where one round ends square to it, and otherwise with one transfinite patch tangent to the three rounds’ ends within the bands’ fit target. Every face is proved within the material it rounds. A request the engine does not take (curved faces, a face set back to a line, a vertex of four edges, an edge’s two ends set back past each other) is rounded as follows.
At a tangent junction the neighbouring wedges’ end caps stand in one
plane with one cross-section, and the boolean’s same-domain resolution
melts them: the blends join without a seam face between them. Two
convex edges of the chain that share a face and turn at a vertex meet
there, the way one edge at a time (fillet_edge) deliberately does
not, since the flush-ended state is what the corner tool
(round_vertex) is built for. Carried on past
the vertex, each band is a straight band of its end section, and two of
one radius cross in the plane through the meeting of their centre lines
that bisects them, where the reflection in that plane carries the one
band’s end section onto the other’s (the shared host flat, the two
walls’ tangent planes at the vertex reflections of each other, to the
fit a marched band is held to). Across a re-entrant turn (an L-shaped
top’s inside corner) both then run on past their caps to that plane,
taking the corner cell they both hold, where the material holds that
cell; across a convex turn of a curved crease both stop in it where the
bands’ own curvature keeps their sections there within that fit. Either
way the two are built from the solid as it stands and joined across the
plane into one wedge, each band’s faces credited to its own edge. Where
the end sections differ (a drafted wall beside a square one) and both
creases are straight, across a re-entrant turn the corner takes what
lies above both bands carried on, bounded by the boolean’s own
intersection of the two, where the material holds it all. Across a
convex turn of two straight creases, whatever their sections, each band
runs out past the vertex as it does alone and the cuts take their union
(walls leaning alike with their feet out each reach past the bisecting
plane under the other’s band, which a meeting there would leave
standing), as they do where one of the two is a drum’s rim (a D-shaped
block’s arc beside its chord, and past where they meet flush, a rib’s
spline wall running into a boss’s rim). Across a re-entrant turn one
of the two may be a drum’s rim, upright or drafted, the material within
the drum, where the
straight band carried on stands nowhere off the drum before the rim’s
cap. Such
junctions stand beside flush ones in a loop or chain, a band crossed at
both ends cut in two halfway along, and two bands meeting at both their
ends meet at each.
Elsewhere (a wider convex turn of two curved bands, or of a curved band
other than a drum’s rim beside one of another kind)
and wherever the meeting does not close, the later seat runs on
through the earlier blend’s band and the cut trims the two bands
against each other along their own intersection, or the caps stand, as
without a junction. Where three or
more edges of the chain meet at one vertex, the corner tool closes it
with the rolling ball’s own patch (the octant of a sphere at a box
corner, the envelope of spheres and cylinders at a vertex no single
ball touches) rather than leaving the bands’ caps standing. The corner
goes first and the bands stop flush against its patch: bands built
first crash into each other at an apex. A corner the tool does not
speak (a concave vertex, more than three surfaces with no shared
ball when one of them is curved) keeps its caps,
which is the honest picture of a corner no ball rolls around. Two
creases meeting on no shared face leave the wedges’ caps standing
likewise.
Only two blends that round the same way trim each other. A wedge’s cut
would eat a fill, and a fill cannot run on through a wedge’s band, so
where a convex edge meets a concave one (an L-bracket’s front edge at
its re-entrant edge) no ball rolls round both. There the request is
rounded in one order whatever its own, and a vertex of three planar
faces and three straight edges, all of them asked, is closed as
round_vertex_setback closes a corner:
each band stopped one of its own widths past the least setback at which
its section clears the others, and one patch G1 to every band end and
face, the same solid in any order.
What solid shares with other shapes is copied before it is
worked on (ogeom_algo::on_own_nodes), which leaves them as they are.
§Errors
As fillet_edge per edge, and additionally if an earlier blend
consumed or split a later edge: a chain whose members interfere is
refused rather than guessed at. Where a convex and a concave edge of the
request meet at a vertex that is not three planar faces and three
straight edges, all asked or one left sharp and convex, the request is
refused by name in any order, and so where a band’s setback reaches its
edge’s far end or the corner’s cell reaches through the solid behind
the vertex. A request of two or more edges also
refuses a ball that sets back past the far side of a face anywhere
along an edge that shares a face or a vertex with another of the
request, since each band’s contacts are checked against the others’
and a contact off its face holds none to check. An edge sharing
neither is held to what fillet_edge holds it to.