Skip to main content

Module offset

Module offset 

Source
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§

OffsetReport
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.