diff --git a/graphicswin.cpp b/graphicswin.cpp index 6e297ac2..10bcab10 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -1183,32 +1183,7 @@ void GraphicsWindow::Paint(int w, int h) { if(SS.group.n >= 5) { if(1) { - SPolyhedron p; ZERO(&p); - - (SS.group.elem[2].polyh).Boolean(&p, 0, - &(SS.group.elem[4].polyh)); - - glEnable(GL_LIGHTING); - GLfloat vec[] = { 0.3f, 0.3f, 0.3f, 1.0 }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, vec); - GLfloat vec2[] = { 1.0f, 0.3f, 0.3f, 1.0 }; - glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, vec2); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - for(i = 0; i < p.l.n; i++) { - glxFillPolygon(&(p.l.elem[i])); - } - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - - p.Clear(); - } else { - SPolygon p; ZERO(&p); - - (SS.group.elem[1].polyg).Boolean(&p, SEdgeList::INTERSECT, - &(SS.group.elem[2].polyg)); - glxDebugPolygon(&p); - p.Clear(); + //XXX } } } diff --git a/polygon.cpp b/polygon.cpp index d3fbe291..2798a565 100644 --- a/polygon.cpp +++ b/polygon.cpp @@ -1,17 +1,5 @@ #include "solvespace.h" -static int ByDouble(const void *av, const void *bv) { - const double *a = (const double *)av; - const double *b = (const double *)bv; - if(*a == *b) { - return 0; - } else if(*a > *b) { - return 1; - } else { - return -1; - } -} - bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) { dest->Clear(); @@ -64,109 +52,6 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt) { } } -void SEdgeList::CopyBreaking(SEdgeList *dest) { - int i, j, k; - - for(i = 0; i < l.n; i++) { - SEdge *ei = &(l.elem[i]); - Vector p0i = ei->a; - Vector dpi = (ei->b).Minus(ei->a); - - double inter[100]; - int inters = 0; - for(j = 0; j < l.n; j++) { - if(i == j) continue; - SEdge *ej = &(l.elem[j]); - Vector p0j = ej->a; - Vector dpj = (ej->b).Minus(ej->a); - - // Find the intersection, if any - Vector dn = dpi.Cross(dpj); - if(dn.Magnitude() < 0.001) continue; // parallel, non-intersecting - Vector dni = dn.Cross(dpi); - Vector dnj = dn.Cross(dpj); - double tj = ((p0i.Minus(p0j)).Dot(dni))/(dpj.Dot(dni)); - double ti = -((p0i.Minus(p0j)).Dot(dnj))/(dpi.Dot(dnj)); - // could also test for skew, but assume it's all in plane so not - - if(ti <= 0 || ti >= 1) continue; - if(tj < -0.001 || tj > 1.001) continue; - - inter[inters++] = ti; - } - inter[inters++] = 0; - inter[inters++] = 1; - qsort(inter, inters, sizeof(inter[0]), ByDouble); - - for(k = 1; k < inters; k++) { - SEdge ne; - ne.tag = 0; - ne.a = p0i.Plus(dpi.ScaledBy(inter[k-1])); - ne.b = p0i.Plus(dpi.ScaledBy(inter[k])); - dest->l.Add(&ne); - } - } -} - -void SEdgeList::CullDuplicates(void) { - int i, j; - for(i = 0; i < l.n; i++) { - SEdge *se = &(l.elem[i]); - if(se->tag) continue; - - if(((se->a).Minus(se->b)).Magnitude() < 0.01) { - se->tag = 1; - continue; - } - - for(j = i+1; j < l.n; j++) { - SEdge *st = &(l.elem[j]); - if(st->tag) continue; - - if(((se->a).Equals(st->a) && (se->b).Equals(st->b)) || - ((se->a).Equals(st->b) && (se->b).Equals(st->a))) - { - // This is an exact duplicate, so mark it as unused now. - st->tag = 1; - break; - } - } - } -} - -bool SEdgeList::BooleanOp(int op, bool inA, bool inB) { - if(op == UNION) { - return inA || inB; - } else if(op == DIFF) { - return inA && (!inB); - } else if(op == INTERSECT) { - return inA && inB; - } else oops(); -} - -void SEdgeList::CullForBoolean(int op, SPolygon *a, SPolygon *b) { - int i; - for(i = 0; i < l.n; i++) { - SEdge *se = &(l.elem[i]); - if(se->tag) continue; - - Vector tp = ((se->a).Plus(se->b)).ScaledBy(0.5); - Vector nudge = ((se->a).Minus(se->b)).Cross(a->normal); - nudge = nudge.WithMagnitude(.01); - Vector tp1 = tp.Plus(nudge); - Vector tp2 = tp.Minus(nudge); - - bool inf1 = BooleanOp(op, a->ContainsPoint(tp1), b->ContainsPoint(tp1)); - bool inf2 = BooleanOp(op, a->ContainsPoint(tp2), b->ContainsPoint(tp2)); - - if((inf1 && inf2) || (!inf1 && !inf2)) { - // The "in polygon" state doesn't change as you cross the edge; - // so it doesn't lie on the output polygon. - se->tag = 1; - } - } -} - void SPolygon::Clear(void) { int i; for(i = 0; i < l.n; i++) { @@ -216,80 +101,6 @@ bool SPolygon::ContainsPoint(Vector p) { return inside; } -void SPolygon::IntersectAgainstPlane(SEdgeList *dest, Vector p0, Vector n) { - if(l.n == 0 || (l.elem[0].l.n == 0)) return; - double od = normal.Dot(l.elem[0].l.elem[0].p); - double d = n.Dot(p0); - - Vector u = (normal.Cross(n)); - if(u.Magnitude() < 0.001) { - if(n.Dot(normal) < 0) od = -od; - if(fabs(od - d) < 0.001) { - // The planes are coincident; so the intersection is a copy of - // this polygon. - MakeEdgesInto(dest); - } - return; - } - - u = u.WithMagnitude(1); - Vector v = normal.Cross(u); - - Vector lp = Vector::AtIntersectionOfPlanes(n, d, normal, od); - double vp = v.Dot(lp); - - double inter[100]; - int inters = 0; - int i; - for(i = 0; i < l.n; i++) { - SContour *sc = &(l.elem[i]); - // The 0.01 is because I mishandle the case where the intersection - // plane goes through a vertex - sc->IntersectAgainstPlane(inter, &inters, u, v, vp); - } - qsort(inter, inters, sizeof(inter[0]), ByDouble); - for(i = 0; i < inters; i += 2) { - SEdge se; - se.tag = 0; - se.a = lp.Plus(u.ScaledBy(inter[i])); - se.b = lp.Plus(u.ScaledBy(inter[i+1])); - dest->l.Add(&se); - } -} - -void SPolygon::CopyBreaking(SPolyhedron *dest, SPolyhedron *against, int how) { - if(l.n == 0 || (l.elem[0].l.n == 0)) return; - Vector p0 = l.elem[0].l.elem[0].p; - - SEdgeList el; ZERO(&el); - int i; - for(i = 0; i < against->l.n; i++) { - SPolygon *pb = &(against->l.elem[i]); - pb->IntersectAgainstPlane(&el, p0, normal); - } - el.CullDuplicates(); - - SPolygon inter; ZERO(&inter); - bool worked = el.AssemblePolygon(&inter, NULL); - inter.normal = normal; - - SPolygon res; ZERO(&res); - if(how == 0) { - this->Boolean(&res, SEdgeList::DIFF, &inter); - res.normal = normal; - } else if(how == 1) { - this->Boolean(&res, SEdgeList::INTERSECT, &inter); - res.normal = normal.ScaledBy(-1); - } else oops(); - - if(res.l.n > 0) { - dest->l.Add(&res); - } - - el.l.Clear(); - inter.Clear(); -} - void SPolygon::FixContourDirections(void) { // Outside curve looks counterclockwise, projected against our normal. int i, j; @@ -314,32 +125,6 @@ void SPolygon::FixContourDirections(void) { } } -bool SPolygon::Boolean(SPolygon *dest, int op, SPolygon *b) { - SEdgeList el; - ZERO(&el); - this->MakeEdgesInto(&el); - b->MakeEdgesInto(&el); - - SEdgeList br; - ZERO(&br); - el.CopyBreaking(&br); - - br.CullDuplicates(); - br.CullForBoolean(op, this, b); - - SEdge e; - bool ret = br.AssemblePolygon(dest, &e); - if(!ret) { - br.l.ClearTags(); - br.CullDuplicates(); - br.CullForBoolean(op, this, b); - } - - br.l.Clear(); - el.l.Clear(); - return ret; -} - void SContour::MakeEdgesInto(SEdgeList *el) { int i; for(i = 0; i < (l.n-1); i++) { @@ -413,37 +198,6 @@ bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) { return inside; } - -void SContour::IntersectAgainstPlane(double *inter, int *inters, - Vector u, Vector v, double vp) -{ - for(int i = 0; i < (l.n - 1); i++) { - double ua = (l.elem[i ].p).Dot(u); - double va = (l.elem[i ].p).Dot(v); - double ub = (l.elem[(i+1)%(l.n-1)].p).Dot(u); - double vb = (l.elem[(i+1)%(l.n-1)].p).Dot(v); - - double u0, v0, du, dv; - - if(va < vb) { - u0 = ua; v0 = va; - du = (ub - ua); dv = (vb - va); - } else { - u0 = ub; v0 = vb; - du = (ua - ub); dv = (va - vb); - } - - if(dv == 0) continue; - - double t = (vp - v0)/dv; - if(t >= 0 && t < 1) { - double ui = u0 + t*du; - // Our line v = vp intersects the edge; record the u value - inter[(*inters)++] = ui; - } - } -} - void SContour::Reverse(void) { int i; for(i = 0; i < (l.n / 2); i++) { @@ -454,40 +208,3 @@ void SContour::Reverse(void) { } } -void SPolyhedron::AddFace(SPolygon *p) { - l.Add(p); -} - -void SPolyhedron::Clear(void) { - int i; - for(i = 0; i < l.n; i++) { - (l.elem[i]).Clear(); - } - l.Clear(); -} - -void SPolyhedron::IntersectAgainstPlane(SEdgeList *d, Vector p0, Vector n) { - int i; - for(i = 0; i < l.n; i++) { - SPolygon *sp = &(l.elem[i]); - sp->IntersectAgainstPlane(d, p0, n); - } -} - -bool SPolyhedron::Boolean(SPolyhedron *dest, int op, SPolyhedron *b) { - int i; - dbp(">>>"); - - for(i = 0; i < l.n; i++) { - SPolygon *sp = &(l.elem[i]); - sp->CopyBreaking(dest, b, 0); - } - - for(i = 0; i < b->l.n; i++) { - SPolygon *sp = &(b->l.elem[i]); - sp->CopyBreaking(dest, this, 1); - } - - return true; -} - diff --git a/polygon.h b/polygon.h index 6d18a459..e8755fce 100644 --- a/polygon.h +++ b/polygon.h @@ -3,7 +3,6 @@ #define __POLYGON_H class SPolygon; -class SPolyhedron; template class SList { @@ -83,22 +82,36 @@ public: void MakeEdgesInto(SEdgeList *el); void FixContourDirections(void); void Clear(void); - - bool Boolean(SPolygon *dest, int op, SPolygon *b); - - void CopyBreaking(SPolyhedron *dest, SPolyhedron *against, int how); - void IntersectAgainstPlane(SEdgeList *dest, Vector p0, Vector n); }; -class SPolyhedron { +class STriangle { public: - SList l; + Vector a, b, c; +}; - void AddFace(SPolygon *p); - void Clear(void); +class SBsp2 { + SEdge edge; +}; - void IntersectAgainstPlane(SEdgeList *dest, Vector p0, Vector n); - bool Boolean(SPolyhedron *dest, int op, SPolyhedron *b); +class SBsp1d { + SEdge edge; +}; + +class SBsp3 { +public: + STriangle tri; + SBsp3 *pos; + SBsp3 *neg; + + SBsp3 *more; + + SBsp2 *edges; +}; + + +class SMesh { +public: + SList l; }; #endif diff --git a/sketch.cpp b/sketch.cpp index b15de602..81389157 100644 --- a/sketch.cpp +++ b/sketch.cpp @@ -383,8 +383,7 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz, void Group::MakePolygons(void) { int i; - polyh.Clear(); - polyg.Clear(); + poly.Clear(); SEdgeList edges; ZERO(&edges); @@ -398,13 +397,13 @@ void Group::MakePolygons(void) { e->GenerateEdges(&edges); } SEdge error; - if(edges.AssemblePolygon(&polyg, &error)) { + if(edges.AssemblePolygon(&poly, &error)) { polyError.yes = false; - polyg.normal = polyg.ComputeNormal(); + poly.normal = poly.ComputeNormal(); } else { polyError.yes = true; polyError.notClosedAt = error; - polyg.Clear(); + poly.Clear(); } } else if(type == EXTRUDE) { Vector translate; @@ -422,7 +421,7 @@ void Group::MakePolygons(void) { edges.l.Clear(); Group *src = SS.GetGroup(opA); - (src->polyg).MakeEdgesInto(&edges); + (src->poly).MakeEdgesInto(&edges); for(i = 0; i < edges.l.n; i++) { SEdge *edge = &(edges.l.elem[i]); edge->a = (edge->a).Plus(t0); @@ -439,7 +438,6 @@ void Group::MakePolygons(void) { } np.normal = n; np.FixContourDirections(); - polyh.AddFace(&np); // Regenerate the edges, with the contour directions fixed up. edges.l.Clear(); @@ -457,7 +455,6 @@ void Group::MakePolygons(void) { np.AddPoint((edge->a).Plus(dt)); np.AddPoint(edge->a); np.normal = ((edge->a).Minus(edge->b).Cross(n)).WithMagnitude(1); - polyh.AddFace(&np); edge->a = (edge->a).Plus(dt); edge->b = (edge->b).Plus(dt); @@ -467,7 +464,6 @@ void Group::MakePolygons(void) { memset(&np, 0, sizeof(np)); if(!edges.AssemblePolygon(&np, NULL)) oops(); np.normal = n.ScaledBy(-1); - polyh.AddFace(&np); } edges.l.Clear(); } @@ -492,27 +488,11 @@ void Group::Draw(void) { } else { int i; glEnable(GL_LIGHTING); - GLfloat vec[] = { 0.3f, 0.3f, 0.3f, 1.0 }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, vec); - GLfloat vec2[] = { 1.0f, 0.3f, 0.3f, 1.0 }; - glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, vec2); - for(i = 0; i < polyh.l.n; i++) { - glxFillPolygon(&(polyh.l.elem[i])); -#if 0 - // Debug stuff to show normals to the faces on-screen - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glxMarkPolygonNormal(&(polyh.l.elem[i])); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); -#endif - } - - GLfloat vec3[] = { 0.3f, 1.0f, 0.3f, 0.5 }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, vec3); - GLfloat vec4[] = { 1.0f, 0.3f, 0.3f, 0.5 }; - glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, vec4); - glxFillPolygon(&polyg); + GLfloat mpf[] = { 0.3f, 1.0f, 0.3f, 0.5 }; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mpf); + GLfloat mpb[] = { 1.0f, 0.3f, 0.3f, 0.5 }; + glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, mpb); + glxFillPolygon(&poly); glDisable(GL_LIGHTING); } diff --git a/sketch.h b/sketch.h index 4075e742..a032b9af 100644 --- a/sketch.h +++ b/sketch.h @@ -106,12 +106,12 @@ public: bool negateV; } wrkpl; - SPolygon polyg; - SPolyhedron polyh; + SPolygon poly; struct { SEdge notClosedAt; bool yes; } polyError; + SMesh mesh; NameStr name; char *DescriptionString(void);