Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions src/srf/boolean.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,36 @@ void SShell::MakeFromIntersectionOf(SShell *a, SShell *b) {
MakeFromBoolean(a, b, SSurface::CombineAs::INTERSECTION);
}

// We will be inserting existing verticies into curves to split them
// todo: this is only using the ends of exact curves, and it is only
// using them to split existing curves, not new intersections.
// It resolves some issues but we could do better. We will need to
// reorder things so the surface intersection curves exist prior to
// splitting any curves at all in order to have their verticies too.
// Better still would be to get curve/surface intersection to work
Comment thread
ruevs marked this conversation as resolved.
// more reliably at the edges - maybe do curve/curve tests as part
// of the curve-surface intersection test.
void SCurve::GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const {
*ptMax = {VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE};
*ptMin = {VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE};

for(int i = 0; i <= exact.deg; i++) {
exact.ctrl[i].MakeMaxMin(ptMax, ptMin);
}
}

// We will be inserting other curve verticies into our curves to split them.
// This is helpful when curved surfaces become tangent along a trim and the
// usual tests for curve-surface intersection don't split the curve at a vertex.
// This is faster than the previous version that split at surface corners and
// handles more buggy cases. It's not clear this is the best way but it works ok.
static void FindVertsOnCurve(List<SInter> *l, const SCurve *curve, SShell *sh) {

Vector amax, amin;
curve->GetAxisAlignedBounding(&amax, &amin);

for(auto sc : sh->curve) {
if(!sc.isExact) continue;

Vector cmax, cmin;
sc.GetAxisAlignedBounding(&cmax, &cmin);

if(Vector::BoundingBoxesDisjoint(amax, amin, cmax, cmin)) {
// They cannot possibly intersect, no curves to generate
continue;
}

for(int i=0; i<2; i++) {
Vector pt = sc.exact.ctrl[ i==0 ? 0 : sc.exact.deg ];
double t;
Expand Down Expand Up @@ -63,11 +81,13 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,

// First find any vertex that lies on our curve.
List<SInter> vertpts = {};
if(agnstA)
FindVertsOnCurve(&vertpts, this, agnstA);
if(agnstB)
FindVertsOnCurve(&vertpts, this, agnstB);

if(isExact) {
if(agnstA)
FindVertsOnCurve(&vertpts, this, agnstA);
if(agnstB)
FindVertsOnCurve(&vertpts, this, agnstB);
}

const SCurvePt *p = pts.First();
ssassert(p != NULL, "Cannot split an empty curve");
SCurvePt prev = *p;
Expand Down
1 change: 1 addition & 0 deletions src/srf/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class SCurve {
SSurface *GetSurfaceB(SShell *a, SShell *b) const;

void Clear();
void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const;
};

// A segment of a curve by which a surface is trimmed: indicates which curve,
Expand Down