本文整理汇总了C++中SBezier类的典型用法代码示例。如果您正苦于以下问题:C++ SBezier类的具体用法?C++ SBezier怎么用?C++ SBezier使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SBezier类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ZERO
int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
if(loop->l.n < 1) oops();
List<int> listOfTrims;
ZERO(&listOfTrims);
SBezier *sb = &(loop->l.elem[loop->l.n - 1]);
// Generate "exactly closed" contours, with the same vertex id for the
// finish of a previous edge and the start of the next one. So we need
// the finish of the last Bezier in the loop before we start our process.
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
id, CO(sb->Finish()));
fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id);
int lastFinish = id + 1, prevFinish = lastFinish;
id += 2;
for(sb = loop->l.First(); sb; sb = loop->l.NextAfter(sb)) {
int curveId = ExportCurve(sb);
int thisFinish;
if(loop->l.NextAfter(sb) != NULL) {
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
id, CO(sb->Finish()));
fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id);
thisFinish = id + 1;
id += 2;
} else {
thisFinish = lastFinish;
}
fprintf(f, "#%d=EDGE_CURVE('',#%d,#%d,#%d,%s);\n",
id, prevFinish, thisFinish, curveId, ".T.");
fprintf(f, "#%d=ORIENTED_EDGE('',*,*,#%d,.T.);\n",
id+1, id);
int oe = id+1;
listOfTrims.Add(&oe);
id += 2;
prevFinish = thisFinish;
}
fprintf(f, "#%d=EDGE_LOOP('',(", id);
int *oe;
for(oe = listOfTrims.First(); oe; oe = listOfTrims.NextAfter(oe)) {
fprintf(f, "#%d", *oe);
if(listOfTrims.NextAfter(oe) != NULL) fprintf(f, ",");
}
fprintf(f, "));\n");
int fb = id + 1;
fprintf(f, "#%d=%s('',#%d,.T.);\n",
fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id);
id += 2;
listOfTrims.Clear();
return fb;
}
示例2: GetBoundingProjd
void SBezierLoop::GetBoundingProjd(Vector u, Vector orig,
double *umin, double *umax)
{
SBezier *sb;
for(sb = l.First(); sb; sb = l.NextAfter(sb)) {
sb->GetBoundingProjd(u, orig, umin, umax);
}
}
示例3: Reverse
void SBezierLoop::Reverse(void) {
l.Reverse();
SBezier *sb;
for(sb = l.First(); sb; sb = l.NextAfter(sb)) {
// If we didn't reverse each curve, then the next curve in list would
// share your start, not your finish.
sb->Reverse();
}
}
示例4: IsCylinder
bool SSurface::IsCylinder(Vector *axis, Vector *center, double *r,
Vector *start, Vector *finish)
{
SBezier sb;
if(!IsExtrusion(&sb, axis)) return false;
if(!sb.IsCircle(*axis, center, r)) return false;
*start = sb.ctrl[0];
*finish = sb.ctrl[2];
return true;
}
示例5: MakePwlInto
void SBezierLoop::MakePwlInto(SContour *sc, double chordTol) {
SBezier *sb;
for(sb = l.First(); sb; sb = l.NextAfter(sb)) {
sb->MakePwlInto(sc, chordTol);
// Avoid double points at join between Beziers; except that
// first and last points should be identical.
if(l.NextAfter(sb) != NULL) {
sc->l.RemoveLast(1);
}
}
// Ensure that it's exactly closed, not just within a numerical tolerance.
if((sc->l.elem[sc->l.n - 1].p).Equals(sc->l.elem[0].p)) {
sc->l.elem[sc->l.n - 1] = sc->l.elem[0];
}
}
示例6: ZERO
//-----------------------------------------------------------------------------
// Assemble curves in sbl into a single loop. The curves may appear in any
// direction (start to finish, or finish to start), and will be reversed if
// necessary. The curves in the returned loop are removed from sbl, even if
// the loop cannot be closed.
//-----------------------------------------------------------------------------
SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
bool *allClosed, SEdge *errorAt)
{
SBezierLoop loop;
ZERO(&loop);
if(sbl->l.n < 1) return loop;
sbl->l.ClearTags();
SBezier *first = &(sbl->l.elem[0]);
first->tag = 1;
loop.l.Add(first);
Vector start = first->Start();
Vector hanging = first->Finish();
int auxA = first->auxA;
sbl->l.RemoveTagged();
while(sbl->l.n > 0 && !hanging.Equals(start)) {
int i;
bool foundNext = false;
for(i = 0; i < sbl->l.n; i++) {
SBezier *test = &(sbl->l.elem[i]);
if((test->Finish()).Equals(hanging) && test->auxA == auxA) {
test->Reverse();
// and let the next test catch it
}
if((test->Start()).Equals(hanging) && test->auxA == auxA) {
test->tag = 1;
loop.l.Add(test);
hanging = test->Finish();
sbl->l.RemoveTagged();
foundNext = true;
break;
}
}
if(!foundNext) {
// The loop completed without finding the hanging edge, so
// it's an open loop
errorAt->a = hanging;
errorAt->b = start;
*allClosed = false;
return loop;
}
}
if(hanging.Equals(start)) {
*allClosed = true;
} else {
// We ran out of edges without forming a closed loop.
errorAt->a = hanging;
errorAt->b = start;
*allClosed = false;
}
return loop;
}
示例7: CullIdenticalBeziers
//-----------------------------------------------------------------------------
// If our list contains multiple identical Beziers (in either forward or
// reverse order), then cull them.
//-----------------------------------------------------------------------------
void SBezierList::CullIdenticalBeziers(void) {
int i, j;
l.ClearTags();
for(i = 0; i < l.n; i++) {
SBezier *bi = &(l.elem[i]), bir;
bir = *bi;
bir.Reverse();
for(j = i + 1; j < l.n; j++) {
SBezier *bj = &(l.elem[j]);
if(bj->Equals(bi) ||
bj->Equals(&bir))
{
bi->tag = 1;
bj->tag = 1;
}
}
}
l.RemoveTagged();
}
示例8: ZERO
void Entity::GenerateEdges(SEdgeList *el, bool includingConstruction) {
if(construction && !includingConstruction) return;
SBezierList sbl;
ZERO(&sbl);
GenerateBezierCurves(&sbl);
int i, j;
for(i = 0; i < sbl.l.n; i++) {
SBezier *sb = &(sbl.l.elem[i]);
List<Vector> lv;
ZERO(&lv);
sb->MakePwlInto(&lv);
for(j = 1; j < lv.n; j++) {
el->AddEdge(lv.elem[j-1], lv.elem[j], style.v);
}
lv.Clear();
}
sbl.Clear();
}
示例9: Bezier
void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) {
Vector t0 = sb->TangentAt(0), t1 = sb->TangentAt(1);
// The curve is correct, and the first derivatives are correct, at the
// endpoints.
SBezier bnr = SBezier::From(
sb->Start(),
sb->Start().Plus(t0.ScaledBy(1.0/3)),
sb->Finish().Minus(t1.ScaledBy(1.0/3)),
sb->Finish());
double tol = SS.ChordTolMm() / SS.exportScale;
// Arbitrary choice, but make it a little finer than pwl tolerance since
// it should be easier to achieve that with the smooth curves.
tol /= 2;
bool closeEnough = true;
int i;
for(i = 1; i <= 3; i++) {
double t = i/4.0;
Vector p0 = sb->PointAt(t),
pn = bnr.PointAt(t);
double d = (p0.Minus(pn)).Magnitude();
if(d > tol) {
closeEnough = false;
}
}
if(closeEnough || depth > 3) {
Bezier(&bnr);
} else {
SBezier bef, aft;
sb->SplitAt(0.5, &bef, &aft);
BezierAsNonrationalCubic(&bef, depth+1);
BezierAsNonrationalCubic(&aft, depth+1);
}
}
示例10: MakeFromRevolutionOf
void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color, Group *group)
{
SBezierLoop *sbl;
int i0 = surface.n, i;
// Normalize the axis direction so that the direction of revolution
// ends up parallel to the normal of the sketch, on the side of the
// axis where the sketch is.
Vector pto;
double md = VERY_NEGATIVE;
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
SBezier *sb;
for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
// Choose the point farthest from the axis; we'll get garbage
// if we choose a point that lies on the axis, for example.
// (And our surface will be self-intersecting if the sketch
// spans the axis, so don't worry about that.)
Vector p = sb->Start();
double d = p.DistanceToLine(pt, axis);
if(d > md) {
md = d;
pto = p;
}
}
}
Vector ptc = pto.ClosestPointOnLine(pt, axis),
up = (pto.Minus(ptc)).WithMagnitude(1),
vp = (sbls->normal).Cross(up);
if(vp.Dot(axis) < 0) {
axis = axis.ScaledBy(-1);
}
// Now we actually build and trim the surfaces.
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
int i, j;
SBezier *sb, *prev;
List<Revolved> hsl = {};
for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
Revolved revs;
for(j = 0; j < 4; j++) {
if(sb->deg == 1 &&
(sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
(sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS)
{
// This is a line on the axis of revolution; it does
// not contribute a surface.
revs.d[j].v = 0;
} else {
SSurface ss = SSurface::FromRevolutionOf(sb, pt, axis,
(PI/2)*j,
(PI/2)*(j+1));
ss.color = color;
if(sb->entity != 0) {
hEntity he;
he.v = sb->entity;
hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
if(SK.entity.FindByIdNoOops(hface) != NULL) {
ss.face = hface.v;
}
}
revs.d[j] = surface.AddAndAssignId(&ss);
}
}
hsl.Add(&revs);
}
for(i = 0; i < sbl->l.n; i++) {
Revolved revs = hsl.elem[i],
revsp = hsl.elem[WRAP(i-1, sbl->l.n)];
sb = &(sbl->l.elem[i]);
prev = &(sbl->l.elem[WRAP(i-1, sbl->l.n)]);
for(j = 0; j < 4; j++) {
SCurve sc;
Quaternion qs = Quaternion::From(axis, (PI/2)*j);
// we want Q*(x - p) + p = Q*x + (p - Q*p)
Vector ts = pt.Minus(qs.Rotate(pt));
// If this input curve generate a surface, then trim that
// surface with the rotated version of the input curve.
if(revs.d[j].v) {
sc = {};
sc.isExact = true;
sc.exact = sb->TransformedBy(ts, qs, 1.0);
(sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = revs.d[j];
sc.surfB = revs.d[WRAP(j-1, 4)];
hSCurve hcb = curve.AddAndAssignId(&sc);
STrimBy stb;
stb = STrimBy::EntireCurve(this, hcb, true);
(surface.FindById(sc.surfA))->trim.Add(&stb);
stb = STrimBy::EntireCurve(this, hcb, false);
(surface.FindById(sc.surfB))->trim.Add(&stb);
}
//.........这里部分代码省略.........
示例11: swap
void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, RgbaColor color)
{
// Make the extrusion direction consistent with respect to the normal
// of the sketch we're extruding.
if((t0.Minus(t1)).Dot(sbls->normal) < 0) {
swap(t0, t1);
}
// Define a coordinate system to contain the original sketch, and get
// a bounding box in that csys
Vector n = sbls->normal.ScaledBy(-1);
Vector u = n.Normal(0), v = n.Normal(1);
Vector orig = sbls->point;
double umax = 1e-10, umin = 1e10;
sbls->GetBoundingProjd(u, orig, &umin, &umax);
double vmax = 1e-10, vmin = 1e10;
sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
// and now fix things up so that all u and v lie between 0 and 1
orig = orig.Plus(u.ScaledBy(umin));
orig = orig.Plus(v.ScaledBy(vmin));
u = u.ScaledBy(umax - umin);
v = v.ScaledBy(vmax - vmin);
// So we can now generate the top and bottom surfaces of the extrusion,
// planes within a translated (and maybe mirrored) version of that csys.
SSurface s0, s1;
s0 = SSurface::FromPlane(orig.Plus(t0), u, v);
s0.color = color;
s1 = SSurface::FromPlane(orig.Plus(t1).Plus(u), u.ScaledBy(-1), v);
s1.color = color;
hSSurface hs0 = surface.AddAndAssignId(&s0),
hs1 = surface.AddAndAssignId(&s1);
// Now go through the input curves. For each one, generate its surface
// of extrusion, its two translated trim curves, and one trim line. We
// go through by loops so that we can assign the lines correctly.
SBezierLoop *sbl;
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
SBezier *sb;
List<TrimLine> trimLines = {};
for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
// Generate the surface of extrusion of this curve, and add
// it to the list
SSurface ss = SSurface::FromExtrusionOf(sb, t0, t1);
ss.color = color;
hSSurface hsext = surface.AddAndAssignId(&ss);
// Translate the curve by t0 and t1 to produce two trim curves
SCurve sc = {};
sc.isExact = true;
sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY, 1.0);
(sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = hs0;
sc.surfB = hsext;
hSCurve hc0 = curve.AddAndAssignId(&sc);
sc = {};
sc.isExact = true;
sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY, 1.0);
(sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = hs1;
sc.surfB = hsext;
hSCurve hc1 = curve.AddAndAssignId(&sc);
STrimBy stb0, stb1;
// The translated curves trim the flat top and bottom surfaces.
stb0 = STrimBy::EntireCurve(this, hc0, false);
stb1 = STrimBy::EntireCurve(this, hc1, true);
(surface.FindById(hs0))->trim.Add(&stb0);
(surface.FindById(hs1))->trim.Add(&stb1);
// The translated curves also trim the surface of extrusion.
stb0 = STrimBy::EntireCurve(this, hc0, true);
stb1 = STrimBy::EntireCurve(this, hc1, false);
(surface.FindById(hsext))->trim.Add(&stb0);
(surface.FindById(hsext))->trim.Add(&stb1);
// And form the trim line
Vector pt = sb->Finish();
sc = {};
sc.isExact = true;
sc.exact = SBezier::From(pt.Plus(t0), pt.Plus(t1));
(sc.exact).MakePwlInto(&(sc.pts));
hSCurve hl = curve.AddAndAssignId(&sc);
// save this for later
TrimLine tl;
tl.hc = hl;
tl.hs = hsext;
trimLines.Add(&tl);
}
int i;
for(i = 0; i < trimLines.n; i++) {
TrimLine *tl = &(trimLines.elem[i]);
SSurface *ss = surface.FindById(tl->hs);
TrimLine *tlp = &(trimLines.elem[WRAP(i-1, trimLines.n)]);
STrimBy stb;
//.........这里部分代码省略.........
示例12: if
//-----------------------------------------------------------------------------
// Report our trim curves. If a trim curve is exact and sbl is not null, then
// add its exact form to sbl. Otherwise, add its piecewise linearization to
// sel.
//-----------------------------------------------------------------------------
void SSurface::MakeSectionEdgesInto(SShell *shell,
SEdgeList *sel, SBezierList *sbl)
{
STrimBy *stb;
for(stb = trim.First(); stb; stb = trim.NextAfter(stb)) {
SCurve *sc = shell->curve.FindById(stb->curve);
SBezier *sb = &(sc->exact);
if(sbl && sc->isExact && (sb->deg != 1 || !sel)) {
double ts, tf;
if(stb->backwards) {
sb->ClosestPointTo(stb->start, &tf);
sb->ClosestPointTo(stb->finish, &ts);
} else {
sb->ClosestPointTo(stb->start, &ts);
sb->ClosestPointTo(stb->finish, &tf);
}
SBezier junk_bef, keep_aft;
sb->SplitAt(ts, &junk_bef, &keep_aft);
// In the kept piece, the range that used to go from ts to 1
// now goes from 0 to 1; so rescale tf appropriately.
tf = (tf - ts)/(1 - ts);
SBezier keep_bef, junk_aft;
keep_aft.SplitAt(tf, &keep_bef, &junk_aft);
sbl->l.Add(&keep_bef);
} else if(sbl && !sel && !sc->isExact) {
// We must approximate this trim curve, as piecewise cubic sections.
SSurface *srfA = shell->surface.FindById(sc->surfA),
*srfB = shell->surface.FindById(sc->surfB);
Vector s = stb->backwards ? stb->finish : stb->start,
f = stb->backwards ? stb->start : stb->finish;
int sp, fp;
for(sp = 0; sp < sc->pts.n; sp++) {
if(s.Equals(sc->pts.elem[sp].p)) break;
}
if(sp >= sc->pts.n) return;
for(fp = sp; fp < sc->pts.n; fp++) {
if(f.Equals(sc->pts.elem[fp].p)) break;
}
if(fp >= sc->pts.n) return;
// So now the curve we want goes from elem[sp] to elem[fp]
while(sp < fp) {
// Initially, we'll try approximating the entire trim curve
// as a single Bezier segment
int fpt = fp;
for(;;) {
// So construct a cubic Bezier with the correct endpoints
// and tangents for the current span.
Vector st = sc->pts.elem[sp].p,
ft = sc->pts.elem[fpt].p,
sf = ft.Minus(st);
double m = sf.Magnitude() / 3;
Vector stan = ExactSurfaceTangentAt(st, srfA, srfB, sf),
ftan = ExactSurfaceTangentAt(ft, srfA, srfB, sf);
SBezier sb = SBezier::From(st,
st.Plus (stan.WithMagnitude(m)),
ft.Minus(ftan.WithMagnitude(m)),
ft);
// And test how much this curve deviates from the
// intermediate points (if any).
int i;
bool tooFar = false;
for(i = sp + 1; i <= (fpt - 1); i++) {
Vector p = sc->pts.elem[i].p;
double t;
sb.ClosestPointTo(p, &t, false);
Vector pp = sb.PointAt(t);
if((pp.Minus(p)).Magnitude() > SS.ChordTolMm()/2) {
tooFar = true;
break;
}
}
if(tooFar) {
// Deviates by too much, so try a shorter span
fpt--;
continue;
} else {
// Okay, so use this piece and break.
sbl->l.Add(&sb);
break;
}
}
// And continue interpolating, starting wherever the curve
// we just generated finishes.
//.........这里部分代码省略.........
示例13: ZERO
hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
// Save the original endpoints, since we're about to delete this entity.
Entity *e01 = SK.GetEntity(he);
SBezierList sbl;
ZERO(&sbl);
e01->GenerateBezierCurves(&sbl);
hEntity hep0 = e01->point[0],
hep1 = e01->point[3+e01->extraPoints],
hep0n = Entity::NO_ENTITY, // the new start point
hep1n = Entity::NO_ENTITY, // the new finish point
hepin = Entity::NO_ENTITY; // the intersection point
// The curve may consist of multiple cubic segments. So find which one
// contains the intersection point.
double t;
int i, j;
for(i = 0; i < sbl.l.n; i++) {
SBezier *sb = &(sbl.l.elem[i]);
if(sb->deg != 3) oops();
sb->ClosestPointTo(pinter, &t, false);
if(pinter.Equals(sb->PointAt(t))) {
// Split that segment at the intersection.
SBezier b0i, bi1, b01 = *sb;
b01.SplitAt(t, &b0i, &bi1);
// Add the two cubic segments this one gets split into.
hRequest r0i = AddRequest(Request::CUBIC, false),
ri1 = AddRequest(Request::CUBIC, false);
// Don't get entities till after adding, realloc issues
Entity *e0i = SK.GetEntity(r0i.entity(0)),
*ei1 = SK.GetEntity(ri1.entity(0));
for(j = 0; j <= 3; j++) {
SK.GetEntity(e0i->point[j])->PointForceTo(b0i.ctrl[j]);
}
for(j = 0; j <= 3; j++) {
SK.GetEntity(ei1->point[j])->PointForceTo(bi1.ctrl[j]);
}
Constraint::ConstrainCoincident(e0i->point[3], ei1->point[0]);
if(i == 0) hep0n = e0i->point[0];
hep1n = ei1->point[3];
hepin = e0i->point[3];
} else {
hRequest r = AddRequest(Request::CUBIC, false);
Entity *e = SK.GetEntity(r.entity(0));
for(j = 0; j <= 3; j++) {
SK.GetEntity(e->point[j])->PointForceTo(sb->ctrl[j]);
}
if(i == 0) hep0n = e->point[0];
hep1n = e->point[3];
}
}
sbl.Clear();
ReplacePointInConstraints(hep0, hep0n);
ReplacePointInConstraints(hep1, hep1n);
return hepin;
}
示例14: ScaleSelfBy
void SBezierList::ScaleSelfBy(double s) {
SBezier *sb;
for(sb = l.First(); sb; sb = l.NextAfter(sb)) {
sb->ScaleSelfBy(s);
}
}
示例15: AddExactIntersectionCurve
void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
SShell *agnstA, SShell *agnstB, SShell *into)
{
SCurve sc = {};
// Important to keep the order of (surfA, surfB) consistent; when we later
// rewrite the identifiers, we rewrite surfA from A and surfB from B.
sc.surfA = h;
sc.surfB = srfB->h;
sc.exact = *sb;
sc.isExact = true;
// Now we have to piecewise linearize the curve. If there's already an
// identical curve in the shell, then follow that pwl exactly, otherwise
// calculate from scratch.
SCurve split, *existing = NULL, *se;
SBezier sbrev = *sb;
sbrev.Reverse();
bool backwards = false;
for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) {
if(se->isExact) {
if(sb->Equals(&(se->exact))) {
existing = se;
break;
}
if(sbrev.Equals(&(se->exact))) {
existing = se;
backwards = true;
break;
}
}
}
if(existing) {
SCurvePt *v;
for(v = existing->pts.First(); v; v = existing->pts.NextAfter(v)) {
sc.pts.Add(v);
}
if(backwards) sc.pts.Reverse();
split = sc;
sc = {};
} else {
sb->MakePwlInto(&(sc.pts));
// and split the line where it intersects our existing surfaces
split = sc.MakeCopySplitAgainst(agnstA, agnstB, this, srfB);
sc.Clear();
}
// Test if the curve lies entirely outside one of the
SCurvePt *scpt;
bool withinA = false, withinB = false;
for(scpt = split.pts.First(); scpt; scpt = split.pts.NextAfter(scpt)) {
double tol = 0.01;
Point2d puv;
ClosestPointTo(scpt->p, &puv);
if(puv.x > -tol && puv.x < 1 + tol &&
puv.y > -tol && puv.y < 1 + tol)
{
withinA = true;
}
srfB->ClosestPointTo(scpt->p, &puv);
if(puv.x > -tol && puv.x < 1 + tol &&
puv.y > -tol && puv.y < 1 + tol)
{
withinB = true;
}
// Break out early, no sense wasting time if we already have the answer.
if(withinA && withinB) break;
}
if(!(withinA && withinB)) {
// Intersection curve lies entirely outside one of the surfaces, so
// it's fake.
split.Clear();
return;
}
#if 0
if(sb->deg == 2) {
dbp(" ");
SCurvePt *prev = NULL, *v;
dbp("split.pts.n = %d", split.pts.n);
for(v = split.pts.First(); v; v = split.pts.NextAfter(v)) {
if(prev) {
Vector e = (prev->p).Minus(v->p).WithMagnitude(0);
SS.nakedEdges.AddEdge((prev->p).Plus(e), (v->p).Minus(e));
}
prev = v;
}
}
#endif // 0
ssassert(!(sb->Start()).Equals(sb->Finish()),
"Unexpected zero-length edge");
split.source = SCurve::Source::INTERSECTION;
into->curve.AddAndAssignId(&split);
}