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
parent
c514ddad54
commit
d72eba8039
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue