|
| | CutTrianglePredicates () |
| | CutTrianglePredicates (CutTrianglePredicates &&) noexcept |
| CutTrianglePredicates & | operator= (CutTrianglePredicates &&) noexcept |
| | ~CutTrianglePredicates () |
| void | reset (const std::array< PreciseVertCoords, 3 > &tri) |
| void | addPoint (VertId v, const PreciseCutPoint &p) |
| bool | less (VertId p, VertId q) const |
| | whether point p comes before point q along the sweep: a strict total order, unless reset or addPoint failed (see failed)
|
| std::optional< Vector2i > | directionByPerturbation (VertId p, VertId q) const |
| bool | ccw (VertId a, VertId b, VertId c) const |
| std::optional< bool > | ccwByLines (VertId a, VertId b, VertId c) const |
| std::optional< bool > | ccwByPerturbation (VertId a, VertId b, VertId c) const |
| bool | ccwFromBehind (VertId b, VertId pivot) const |
| | whether the triangle of a point far behind pivot against the sweep, b and pivot is counterclockwise, for distinct b and pivot
|
| bool | failed () const |
exact predicates on the points inside one triangle cut along its intersections with other triangles, for a sweep line over the triangle; they never contradict the boolean's exact predicates, because every point gets the same simulation-of-simplicity perturbation by vertex ids as in orient3d, and a point is on the side of a cut where the boolean's predicates put it; the crossings of a segment with the triangle defined alike (the edges of a multiple edge of another mesh), which that perturbation cannot tell apart and the boolean's predicates never compare, are told apart by the triangles of their edges: each edge is shifted by an amount infinitely smaller than every term of the perturbation, toward the third vertices of its triangles (PreciseCutPoint::wedge), or away from them if the triangles of another edge defined alike are in the angle between its own ones, so that the contours of two edges whose sheets touch along the segment without crossing do not cross either, while those of crossing sheets do; a crossing of two cuts is the point where the perturbed planes of the triangle and of the two cuts meet, so it is on the side of every other plane that the perturbation puts it on, as a vertex is; the sweep goes over the projection of the perturbed triangle on the plane of the two axes least aligned with its normal (dropping the axis of the largest component of the normal, the first one of equal components, or the axis of the leading term of the perturbed normal if the exact one is zero), meeting the points in the order of one linear functional, which is nearly the first projected coordinate; the const members may be called concurrently (less from a parallel sort), while reset and addPoint must not run together with any other member
| void MR::CutTrianglePredicates::addPoint |
( |
VertId | v, |
|
|
const PreciseCutPoint & | p ) |
sets point v: a vertex of the triangle, or a crossing of one of its sides with another triangle, or a crossing of an edge of another triangle with this triangle (whose tri is then the triangle of reset), or a crossing of two cuts of this triangle by the planes of tri and tri2 (a valid tri2 makes it one, and its seg and wedge are ignored then); v indexes a vector of the points, resized to the largest v + 1, so the points take small local ids, not those of the mesh vertices; a crossing is inside the triangle it crosses, as doTriangleSegmentIntersect finds them, which only Debug checks, since it takes several orient3d per point, and a crossing of two cuts is where the segments of the cuts in this triangle cross, of which Debug checks only that it is not outside this triangle; a segment in the plane of its triangle crosses it after the perturbation, at a point that tends to an end of the segment or to a point inside it, and two cuts parallel before the perturbation cross after it, at a point that tends to a point of both; setting a point again forgets the orders found for its old definition, but not a failure, and so does setting one with a wedge after points defined alike were compared, since it may change their shifts; a vertex point that is not a corner of the triangle, repeated ids, a segment with an end on a vertex of its own triangle, a segment off the sides with a triangle other than this one (as one with a single end at a corner), a segment that does not cross the plane of its triangle, two cuts by the same triangle (with three common vertex ids, while distinct triangles in one plane give two parallel cuts, which cross as said above), a cut along a side or by this triangle (by a triangle with two or three corners of this triangle), two cuts whose crossing is another point also after the perturbation (by triangles with a common corner of this triangle, or with two common vertices, whose edge they cross where it crosses this triangle), and two cuts that stay parallel after the perturbation or whose crossing goes to infinity as it vanishes are failures (see failed)
| bool MR::CutTrianglePredicates::ccw |
( |
VertId | a, |
|
|
VertId | b, |
|
|
VertId | c ) const |
|
nodiscard |
whether triangle abc of distinct points is counterclockwise in the projection, for any three points: the first rule that applies decides, of the rounded coordinates (if their errors cannot change the sign), a side through two of the points, and, with the answers kept till reset since the sweep asks about the same triangles often, a plane line through two of them (the lines of ccwByLines), the exact positions, and the expansion of the perturbation; where several rules apply, they agree
| std::optional< bool > MR::CutTrianglePredicates::ccwByLines |
( |
VertId | a, |
|
|
VertId | b, |
|
|
VertId | c ) const |
|
nodiscard |
the same as ccw, decided by a line through two of the points known from their definitions, as the ends of every edge of the cut triangle are: one side of the triangle, or the plane of another triangle (by which the cut along the line goes, also from a vertex of both at selfBoolean's folds), or the plane vcd through a vertex v of the triangle and an edge cd of another one (for v and the crossing of cd with this triangle, at every vertex), or the plane through two edges with a common vertex (for their crossings with this triangle), which ccw needs only for points on one line before the perturbation; a crossing of two cuts is on both of them; the points on one side stay on one line after the perturbation, and they are taken as bulging inward a little, so three of them make a counterclockwise triangle if they come in the order from vertex i+1 to vertex i of side i, up to a cyclic shift; so are the points on a cut with a crossing of two cuts among them, as the pieces of a cut split at its crossings are, bulging to the left of the cut in the direction that the sweep goes along it; where the line has the third point too otherwise, two of the points are defined alike in valid input, and the shifts of their edges decide; with a crossing of two cuts among the points, the first-order term of the shifts decides before the bulge, since only the shifts move those two apart (a failure if that term is zero, as with the difference of the shifts along the cut also after the perturbation, and so for a third point that is not a crossing of two cuts too, if a crossing of two cuts is on the line); nullopt if no two of the points are on a known line
| std::optional< bool > MR::CutTrianglePredicates::ccwByPerturbation |
( |
VertId | a, |
|
|
VertId | b, |
|
|
VertId | c ) const |
|
nodiscard |
the same as ccw found by expanding the perturbation alone, which is slow, while ccw decides most triangles by faster rules; nullopt if the points are on one line after the perturbation too, as the points of one side are, and two points defined alike, or if the expansion reaches a stage whose degrees do not fit in int64, which only crossings of two cuts with many vertices can give (as three crossings with no common plane take 21 vertices)
| bool MR::CutTrianglePredicates::failed |
( |
| ) |
const |
|
nodiscard |
whether the input broke a precondition that reset or addPoint checks, or a predicate met points it cannot tell apart: two points defined alike that the shifts of their edges do not tell apart (a vertex twice, crossings of a side, crossings without wedges or with the same one, or with the segment parallel to the triangle before the perturbation, as with a zero normal, or crossings of the same two cuts), three points defined alike with their shifts on one line, two points defined alike on a known line (see ccwByLines) with a crossing of two cuts, among the points of the triangle or not, with the difference of their shifts along the line also after the perturbation, three points off the sides on one line also after the perturbation and without a crossing of two cuts among them (as three crossings of one cut by edges, while valid input has two at most, apart from points defined alike), or points whose expansion of the perturbation reaches a stage whose degrees do not fit in int64 (see ccwByPerturbation); it stays set till reset; the caller checks it after the addPoint calls and calls no predicate on the point of a failed addPoint, since they take the points as valid (less may be cyclic then, and Debug asserts may fire), while predicates on the other points stay callable; a failure that a predicate finds leaves the predicates callable, with arbitrary answers that the caller discards, and less a strict total order (points defined alike compare alike with every other point, and by their ids with one another if their shifts do not tell them apart)
| void MR::CutTrianglePredicates::reset |
( |
const std::array< PreciseVertCoords, 3 > & | tri | ) |
|
starts a new triangle with three distinct vertex ids: forgets all points, the orders and orientations found by the slower rules, and the failure, keeping the memory of the points for the next triangle; the vertices may come in any order, since the projection shows them counterclockwise around their right-hand normal, which puts the triangle on the left of every side i, from tri[i] to tri[i+1]