Expand description
Offsetting an editable mesh: every face moved along its outward normal by one distance, the folds that leaves repaired.
§Placing a vertex
A face’s outward normal is the way its corners wind counter-clockwise.
About each vertex, the faces of its fan are taken in turn, and an edge
between two of them whose normals turn by more than OFFSET_EDGE_ANGLE
(30°) is an edge of the offset. The edges, and the rims, part the fan
into sectors; a closed fan with fewer than two edges is one sector. Each
sector’s normal is the mean of its faces’ unit normals weighted by the
faces’ angles at the vertex: the normals smoothed within the sector and
never across an edge.
The sectors’ normals fix the directions the vertex is held in: the
heaviest sector’s normal, then, of the sectors whose normals turn by
more than the edge angle from each normal taken, the one whose normal
has the largest part square to the directions taken, that part’s
direction, up to three. Within the directions taken, the
vertex moves by the step x that minimises Σ α (n · x − d)² over its
faces, n a face’s unit normal and α its angle at the vertex: least
squares weighted by corner angle, so that each face ends as near
distance d from where it was as the vertex can put it. A vertex on a
flat stretch moves by d along the normal, one on an edge between faces
square to each other by √2 d, and the corner of a box by √3 d, to
where the offset faces’ planes meet. No vertex moves farther than
OFFSET_FARTHEST (3) times |d|: a longer step is shortened along
its line, as computed.
§Folds
Where the offset faces’ planes meet before the faces end, as beside a convex edge offset inward or a concave one offset outward, the vertices within reach of the edge overshoot it and their faces fold over. Folds are repaired in two steps.
First, overshooting vertices are pushed back. A vertex moved in one or
two directions that ends nearer than |d| to the mesh as it was, to a
face it stands in front of, on the side the offset goes, and that turns
by at least the edge angle from the plane or line the vertex may still
slide in, slides in it onto that face’s offset plane, and is then held
to that plane too. Faces are looked for about where the vertex was
placed, the nearest first, and again for a second push along the line
the first leaves. A slide that would take the vertex farther than the
cap from where it started is not made. A strip that overshot an edge
so lands on the edge, and a vertex in reach of two edges on the corner
where they meet. Faces of one smooth stretch never push each other, so
the residuals least squares leaves on a curved surface stay; nor do
faces the vertex stands behind, so the offset of a piece thinner than
twice the distance, whose sides pass through each other, is not
repaired. These vertices are counted in OffsetReport::eased.
Then folded faces are collapsed. A face is folded when it turns from the way it faced before the offset by more than the edge angle, over included, or is a sliver, its height within the rounding of its corners’ coordinates; a face that was a sliver before is passed over. Each folded face, lowest-numbered first, has an edge collapsed: one of its corners merged into another, which keeps its position and takes in the merged one’s source vertices. The corner merged is the one held in the fewest directions, so a vertex of a flat stretch merges into one on an edge and that into a corner; ties go to the highest-numbered corner. It merges into the corner held in the most directions, ties to the nearest, then the lowest-numbered. A collapse is made only where it keeps the mesh a manifold, the two vertices sharing no neighbour but the corners across the edge, no face about one closing over the edge with a face about the other, and a vertex on a rim merging only along the rim; and only where it turns no face it moves by more than the edge angle short of a sliver. The faces about the vertex merged into are then looked at again. A strip pushed onto an edge so merges into it, and the faces left lie on the offset planes.
Each collapse takes a vertex away, so the repair ends. A folded face no
collapse may repair is left, and counted in OffsetReport::folded.
§A region
With a region, the faces whose corners are all in it move and the rest stay. A vertex the region shares with faces outside it is parted in two: the vertex keeps its number and moves with the region’s faces, placed from them alone, and a new vertex, with its source, stays with the faces outside. Each edge between a face of the region and one outside becomes a wall of two faces joining the two copies of its ends, so the region moves as a step and a closed mesh stays closed.
§What stays
Vertex and face numbers stay, but for the vertices merged, which are
gone, the faces collapsed, which are removed, and the vertices and faces
a region’s wall adds, numbered after every one there is. A vertex with
no face does not move. A vertex Editable::non_manifold reports moves
with its own fan like any other, so the copies of a point several fans
meet part, but is never merged; edges of three or more faces are joined
again as they then stand.
Structs§
- Offset
Report - What an offset did besides moving the vertices.
Constants§
- OFFSET_
EDGE_ ANGLE - The angle, in radians, beyond which the normals of two faces meeting at an edge turn for the edge to be one the offset keeps: 30°.
- OFFSET_
FARTHEST - The farthest a vertex moves, as a multiple of the offset distance.