Create intersection curves from existing ones.

When a plane coinsides with a seam we need to copy that trim curve. The existing curve belongs to the original shell surfaces and an intersection is otherwise not found. Fixes #540.
pull/735/head
phkahler 2020-10-09 15:10:22 -04:00
parent c514ddad54
commit d72eba8039
2 changed files with 51 additions and 0 deletions

View File

@ -342,6 +342,7 @@ public:
void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const;
bool CoincidentWithPlane(Vector n, double d) const;
bool CoincidentWith(SSurface *ss, bool sameNormal) const;
bool ContainsPlaneCurve(SCurve *sc) const;
bool IsExtrusion(SBezier *of, Vector *along) const;
bool IsCylinder(Vector *axis, Vector *center, double *r,
Vector *start, Vector *finish) const;

View File

@ -313,6 +313,38 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
inters.Clear();
lv.Clear();
} else {
if((degm == 1 && degn == 1) || (b->degm == 1 && b->degn == 1)) {
// we should only be here if just one surface is a plane because the
// plane-plane case was already handled above. Need to check the other
// nonplanar surface for trim curves that lie in the plane and are not
// already trimming both surfaces. This happens when we cut a Lathe shell
// on one of the seams for example.
// This also seems necessary to merge some coincident surfaces.
SSurface *splane, *sext;
SShell *shext;
if(degm == 1 && degn == 1) { // this and other checks assume coplanar ctrl pts.
splane = this;
sext = b;
shext = agnstB;
} else {
splane = b;
sext = this;
shext = agnstA;
}
SCurve *sc;
for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) {
if(sc->source == SCurve::Source::INTERSECTION) continue;
if(!sc->isExact) continue;
if((sc->surfA != sext->h) && (sc->surfB != sext->h)) continue;
// we have a curve belonging to the curved surface and not the plane.
// does it lie completely in the plane?
if(splane->ContainsPlaneCurve(sc)) {
SBezier bezier = sc->exact;
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
}
}
}
// Try intersecting the surfaces numerically, by a marching algorithm.
// First, we find all the intersections between a surface and the
// boundary of the other surface.
@ -505,6 +537,24 @@ bool SSurface::CoincidentWithPlane(Vector n, double d) const {
return true;
}
//-----------------------------------------------------------------------------
// Does a planar surface contain a curve? Does the curve lie completely in plane?
//-----------------------------------------------------------------------------
bool SSurface::ContainsPlaneCurve(SCurve *sc) const {
if(degm != 1 || degn != 1) return false;
if(!sc->isExact) return false; // we don't handle those (yet?)
Vector p = ctrl[0][0];
Vector n = NormalAt(0, 0).WithMagnitude(1);
double d = n.Dot(p);
// check all control points on the curve
for(int i=0; i<= sc->exact.deg; i++) {
if(fabs(n.Dot(sc->exact.ctrl[i]) - d) > LENGTH_EPS) return false;
}
return true;
}
//-----------------------------------------------------------------------------
// In our shell, find all surfaces that are coincident with the prototype
// surface (with same or opposite normal, as specified), and copy all of