diff --git a/constraint.cpp b/constraint.cpp index 1baf71a..de19898 100644 --- a/constraint.cpp +++ b/constraint.cpp @@ -21,15 +21,15 @@ void Constraint::MenuConstrain(int id) { c.ptB = gs.point[1]; } else if(gs.lineSegments == 1 && gs.n == 1) { c.type = PT_PT_DISTANCE; - c.ptA = gs.entity[0].point(16); - c.ptB = gs.entity[0].point(16+3); + Entity *e = SS.GetEntity(gs.entity[0]); + c.ptA = e->assoc[0]; + c.ptB = e->assoc[1]; } else { Error("Bad selection for distance / diameter constraint."); return; } c.disp.offset = Vector::MakeFrom(50, 50, 50); c.exprA = Expr::FromString("1+3+2")->DeepCopyKeep(); - FreeAllExprs(); AddConstraint(&c); break; diff --git a/drawconstraint.cpp b/drawconstraint.cpp index d9f4c55..a82b894 100644 --- a/drawconstraint.cpp +++ b/drawconstraint.cpp @@ -16,10 +16,11 @@ void Constraint::DrawOrGetDistance(void) { Vector gu = SS.GW.projUp; Vector gn = gr.Cross(gu); + glxColor(1, 0.3, 1); switch(type) { case PT_PT_DISTANCE: { - Vector ap = SS.GetPoint(ptA)->GetCoords(); - Vector bp = SS.GetPoint(ptB)->GetCoords(); + Vector ap = SS.GetEntity(ptA)->GetPointCoords(); + Vector bp = SS.GetEntity(ptB)->GetPointCoords(); Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset); diff --git a/dsc.h b/dsc.h index 7751299..46b856f 100644 --- a/dsc.h +++ b/dsc.h @@ -91,7 +91,7 @@ public: T *FindById(H h) { T *t = FindByIdNoOops(h); if(!t) { - dbp("failed to look up item %16lx, searched %d items", h.v, n); + dbp("failed to look up item %08x, searched %d items", h.v, n); oops(); } return t; diff --git a/entity.cpp b/entity.cpp index ade16e8..aacd3e1 100644 --- a/entity.cpp +++ b/entity.cpp @@ -1,14 +1,14 @@ #include "solvespace.h" char *Entity::DescriptionString(void) { - Request *r = SS.GetRequest(request()); + Request *r = SS.GetRequest(h.request()); return r->DescriptionString(); } void Entity::Get2dCsysBasisVectors(Vector *u, Vector *v) { double q[4]; for(int i = 0; i < 4; i++) { - q[i] = SS.param.FindById(param(i))->val; + q[i] = SS.GetParam(param.h[i])->val; } Quaternion quat = Quaternion::MakeFrom(q[0], q[1], q[2], q[3]); @@ -16,6 +16,66 @@ void Entity::Get2dCsysBasisVectors(Vector *u, Vector *v) { *v = quat.RotationV(); } +bool Entity::IsPoint(void) { + switch(type) { + case POINT_IN_3D: + case POINT_IN_2D: + return true; + default: + return false; + } +} + +bool Entity::IsFromReferences(void) { + hRequest hr = h.request(); + if(hr.v == Request::HREQUEST_REFERENCE_XY.v) return true; + if(hr.v == Request::HREQUEST_REFERENCE_YZ.v) return true; + if(hr.v == Request::HREQUEST_REFERENCE_ZX.v) return true; + return false; +} + +void Entity::ForcePointTo(Vector p) { + switch(type) { + case POINT_IN_3D: + SS.GetParam(param.h[0])->ForceTo(p.x); + SS.GetParam(param.h[1])->ForceTo(p.y); + SS.GetParam(param.h[2])->ForceTo(p.z); + break; + + case POINT_IN_2D: { + Entity *c = SS.GetEntity(csys); + Vector u, v; + c->Get2dCsysBasisVectors(&u, &v); + SS.GetParam(param.h[0])->ForceTo(p.Dot(u)); + SS.GetParam(param.h[1])->ForceTo(p.Dot(v)); + break; + } + default: oops(); + } +} + +Vector Entity::GetPointCoords(void) { + Vector p; + switch(type) { + case POINT_IN_3D: + p.x = SS.GetParam(param.h[0])->val; + p.y = SS.GetParam(param.h[1])->val; + p.z = SS.GetParam(param.h[2])->val; + break; + + case POINT_IN_2D: { + Entity *c = SS.GetEntity(csys); + Vector u, v; + c->Get2dCsysBasisVectors(&u, &v); + p = u.ScaledBy(SS.GetParam(param.h[0])->val); + p = p.Plus(v.ScaledBy(SS.GetParam(param.h[1])->val)); + break; + } + default: oops(); + } + return p; +} + void Entity::LineDrawOrGetDistance(Vector a, Vector b) { if(dogd.drawing) { glBegin(GL_LINE_STRIP); @@ -46,11 +106,41 @@ double Entity::GetDistance(Point2d mp) { return dogd.dmin; } -void Entity::DrawOrGetDistance(void) { +void Entity::DrawOrGetDistance(void) { + glxColor(1, 1, 1); + switch(type) { + case POINT_IN_3D: + case POINT_IN_2D: { + Entity *isfor = SS.GetEntity(h.request().entity(0)); + if(!SS.GW.show2dCsyss && isfor->type == Entity::CSYS_2D) break; + + Vector v = GetPointCoords(); + + if(dogd.drawing) { + double s = 4; + Vector r = SS.GW.projRight.ScaledBy(s/SS.GW.scale); + Vector d = SS.GW.projUp.ScaledBy(s/SS.GW.scale); + + glxColor(0, 0.8, 0); + glBegin(GL_QUADS); + glxVertex3v(v.Plus (r).Plus (d)); + glxVertex3v(v.Plus (r).Minus(d)); + glxVertex3v(v.Minus(r).Minus(d)); + glxVertex3v(v.Minus(r).Plus (d)); + glEnd(); + } else { + Point2d pp = SS.GW.ProjectPoint(v); + dogd.dmin = pp.DistanceTo(dogd.mp) - 8; + } + break; + } + case CSYS_2D: { + if(!SS.GW.show2dCsyss) break; + Vector p; - p = SS.point.FindById(point(16))->GetCoords(); + p = SS.GetEntity(assoc[0])->GetPointCoords(); Vector u, v; Get2dCsysBasisVectors(&u, &v); @@ -65,28 +155,25 @@ void Entity::DrawOrGetDistance(void) { Vector mm = p.Minus(us).Minus(vs); Vector mp = p.Minus(us).Plus (vs); + glxColor(0, 0.4, 0.4); LineDrawOrGetDistance(pp, pm); LineDrawOrGetDistance(pm, mm); LineDrawOrGetDistance(mm, mp); LineDrawOrGetDistance(mp, pp); if(dogd.drawing) { - Request *r = SS.request.FindById(this->request()); glPushMatrix(); glxTranslatev(mm); glxOntoCsys(u, v); - glxWriteText(r->DescriptionString()); + glxWriteText(DescriptionString()); glPopMatrix(); } break; } - case DATUM_POINT: - // All display is handled by the generated point. - break; case LINE_SEGMENT: { - Vector a = SS.point.FindById(point(16))->GetCoords(); - Vector b = SS.point.FindById(point(16+3))->GetCoords(); + Vector a = SS.GetEntity(assoc[0])->GetPointCoords(); + Vector b = SS.GetEntity(assoc[1])->GetPointCoords(); LineDrawOrGetDistance(a, b); break; } diff --git a/expr.h b/expr.h index d512cae..24bafea 100644 --- a/expr.h +++ b/expr.h @@ -45,7 +45,6 @@ public: double v; hParam parh; Param *parp; - hPoint point; hEntity entity; // For use while parsing diff --git a/file.cpp b/file.cpp index d09dbdc..c5f17af 100644 --- a/file.cpp +++ b/file.cpp @@ -41,14 +41,6 @@ bool SolveSpace::SaveToFile(char *filename) { fprintf(fh, "AddEntity\n\n"); } - for(i = 0; i < point.n; i++) { - Point *p = &(point.elem[i]); - fprintf(fh, "Point.h.v=%08x\n", p->h.v); - fprintf(fh, "Point.type=%d\n", p->type); - fprintf(fh, "Point.csys.v=%08x\n", p->csys.v); - fprintf(fh, "AddPoint\n\n"); - } - for(i = 0; i < constraint.n; i++) { Constraint *c = &(constraint.elem[i]); fprintf(fh, "Constraint.h.v=%08x\n", c->h.v); diff --git a/glhelper.cpp b/glhelper.cpp index 1b77e53..0f60b03 100644 --- a/glhelper.cpp +++ b/glhelper.cpp @@ -3,6 +3,8 @@ // A public-domain Hershey vector font ("Simplex"). #include "font.table" +static bool ColorLocked; + void glxWriteText(char *str) { double scale = 0.7/SS.GW.scale; @@ -54,3 +56,22 @@ void glxOntoCsys(Vector u, Vector v) 0, 0, 0, 1); glMultMatrixd(mat); } + +void glxLockColorTo(double r, double g, double b) +{ + ColorLocked = false; + glxColor(r, g, b); + ColorLocked = true; +} + +void glxUnlockColor(void) +{ + ColorLocked = false; +} + +void glxColor(double r, double g, double b) +{ + if(!ColorLocked) { + glColor3f((GLfloat)r, (GLfloat)g, (GLfloat)b); + } +} diff --git a/graphicswin.cpp b/graphicswin.cpp index 1ea7293..48b2a01 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -138,9 +138,9 @@ void GraphicsWindow::MenuView(int id) { SS.GW.GroupSelection(); Entity *e = NULL; if(SS.GW.gs.n == 1 && SS.GW.gs.csyss == 1) { - e = SS.entity.FindById(SS.GW.gs.entity[0]); + e = SS.GetEntity(SS.GW.gs.entity[0]); } else if(SS.GW.activeCsys.v != Entity::NO_CSYS.v) { - e = SS.entity.FindById(SS.GW.activeCsys); + e = SS.GetEntity(SS.GW.activeCsys); } if(e) { // A quaternion with our original rotation @@ -160,7 +160,7 @@ void GraphicsWindow::MenuView(int id) { // And also get the offsets. Vector offset0 = SS.GW.offset; - Vector offsetf = SS.point.FindById(e->point(16))->GetCoords(); + Vector offsetf = SS.GetEntity(e->assoc[0])->GetPointCoords(); // Animate transition, unless it's a tiny move. SDWORD dt = (mp < 0.01) ? (-20) : (SDWORD)(100 + 1000*mp); @@ -241,15 +241,8 @@ void GraphicsWindow::MenuEdit(int id) { Selection *s = &(SS.GW.selection[i]); hRequest r; r.v = 0; - if(s->point.v) { - Point *pt = SS.GetPoint(s->point); - Entity *e = SS.GetEntity(pt->entity()); - if(e->type == Entity::DATUM_POINT) { - r = e->request(); - } - } else if(s->entity.v) { - Entity *e = SS.GetEntity(s->entity); - r = e->request(); + if(s->entity.v) { + r = s->entity.request(); } if(r.v) SS.request.Tag(r, 1); } @@ -299,11 +292,11 @@ c: } } -void GraphicsWindow::UpdateDraggedHPoint(hPoint hp, double mx, double my) { - Point *p = SS.point.FindById(hp); - Vector pos = p->GetCoords(); +void GraphicsWindow::UpdateDraggedEntity(hEntity hp, double mx, double my) { + Entity *p = SS.GetEntity(hp); + Vector pos = p->GetPointCoords(); UpdateDraggedPoint(&pos, mx, my); - p->ForceTo(pos); + p->ForcePointTo(pos); } void GraphicsWindow::UpdateDraggedPoint(Vector *pos, double mx, double my) { @@ -358,9 +351,12 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, } else if(leftDown) { // We are left-dragging. This is often used to drag points, or // constraint labels. - if(hover.point.v && !hover.point.isFromReferences()) { + if(hover.entity.v && + SS.GetEntity(hover.entity)->IsPoint() && + !SS.GetEntity(hover.entity)->IsFromReferences()) + { ClearSelection(); - UpdateDraggedHPoint(hover.point, x, y); + UpdateDraggedEntity(hover.entity, x, y); } else if(hover.constraint.v && SS.GetConstraint(hover.constraint)->HasLabel()) { @@ -370,7 +366,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, } } else { if(pendingOperation == PENDING_OPERATION_DRAGGING_POINT) { - UpdateDraggedHPoint(pendingPoint, x, y); + UpdateDraggedEntity(pendingPoint, x, y); } else { // Do our usual hit testing, for the selection. Selection s; @@ -384,24 +380,21 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, } bool GraphicsWindow::Selection::Equals(Selection *b) { - if(point.v != b->point.v) return false; if(entity.v != b->entity.v) return false; if(constraint.v != b->constraint.v) return false; return true; } bool GraphicsWindow::Selection::IsEmpty(void) { - if(point.v) return false; if(entity.v) return false; if(constraint.v) return false; return true; } void GraphicsWindow::Selection::Clear(void) { - point.v = entity.v = constraint.v = 0; + entity.v = constraint.v = 0; } void GraphicsWindow::Selection::Draw(void) { - if(point.v) SS.point. FindById(point )->Draw(); - if(entity.v) SS.entity. FindById(entity )->Draw(); - if(constraint.v) SS.constraint.FindById(constraint)->Draw(); + if(entity.v) SS.GetEntity (entity )->Draw(); + if(constraint.v) SS.GetConstraint(constraint)->Draw(); } void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) { @@ -410,21 +403,13 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) { memset(dest, 0, sizeof(*dest)); - // Do the points + // Do the entities for(i = 0; i < SS.entity.n; i++) { d = SS.entity.elem[i].GetDistance(mp); if(d < 10 && d < dmin) { memset(dest, 0, sizeof(*dest)); dest->entity = SS.entity.elem[i].h; - } - } - - // Entities - for(i = 0; i < SS.point.n; i++) { - d = SS.point.elem[i].GetDistance(mp); - if(d < 10 && d < dmin) { - memset(dest, 0, sizeof(*dest)); - dest->point = SS.point.elem[i].h; + dmin = d; } } @@ -434,6 +419,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) { if(d < 10 && d < dmin) { memset(dest, 0, sizeof(*dest)); dest->constraint = SS.constraint.elem[i].h; + dmin = d; } } } @@ -452,10 +438,6 @@ void GraphicsWindow::GroupSelection(void) { int i; for(i = 0; i < MAX_SELECTED; i++) { Selection *s = &(selection[i]); - if(s->point.v) { - gs.point[(gs.points)++] = s->point; - (gs.n)++; - } if(s->entity.v) { gs.entity[(gs.entities)++] = s->entity; (gs.n)++; @@ -465,6 +447,9 @@ void GraphicsWindow::GroupSelection(void) { case Entity::CSYS_2D: (gs.csyss)++; break; case Entity::LINE_SEGMENT: (gs.lineSegments)++; break; } + if(e->IsPoint()) { + gs.point[(gs.points)++] = s->entity; + } } } } @@ -503,20 +488,21 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) { switch(pendingOperation) { case MNU_DATUM_POINT: hr = AddRequest(Request::DATUM_POINT); - SS.point.FindById(hr.entity(0).point(16))->ForceTo(v); + SS.GetEntity(hr.entity(0))->ForcePointTo(v); pendingOperation = 0; break; case MNU_LINE_SEGMENT: hr = AddRequest(Request::LINE_SEGMENT); - SS.point.FindById(hr.entity(0).point(16))->ForceTo(v); + SS.GetEntity(hr.entity(1))->ForcePointTo(v); pendingOperation = PENDING_OPERATION_DRAGGING_POINT; - pendingPoint = hr.entity(0).point(16+3); + pendingPoint = hr.entity(2); pendingDescription = "click to place next point of line"; - SS.point.FindById(pendingPoint)->ForceTo(v); + SS.GetEntity(pendingPoint)->ForcePointTo(v); break; case PENDING_OPERATION_DRAGGING_POINT: + // The MouseMoved event has already dragged it under the cursor. pendingOperation = 0; break; @@ -629,15 +615,10 @@ void GraphicsWindow::Paint(int w, int h) { int i; // First, draw the entire scene. - glColor3f(1, 1, 1); + glxUnlockColor(); for(i = 0; i < SS.entity.n; i++) { SS.entity.elem[i].Draw(); } - glColor3f(0, 0.8f, 0); - for(i = 0; i < SS.point.n; i++) { - SS.point.elem[i].Draw(); - } - glColor3f(1.0f, 0, 1.0f); for(i = 0; i < SS.constraint.n; i++) { SS.constraint.elem[i].Draw(); } @@ -645,11 +626,11 @@ void GraphicsWindow::Paint(int w, int h) { // Then redraw whatever the mouse is hovering over, highlighted. Have // to disable the depth test, so that we can overdraw. glDisable(GL_DEPTH_TEST); - glColor3f(1, 1, 0); + glxLockColorTo(1, 1, 0); hover.Draw(); // And finally draw the selection, same mechanism. - glColor3f(1, 0, 0); + glxLockColorTo(1, 0, 0); for(i = 0; i < MAX_SELECTED; i++) { selection[i].Draw(); } diff --git a/sketch.cpp b/sketch.cpp index e8ab248..07ea0f4 100644 --- a/sketch.cpp +++ b/sketch.cpp @@ -17,15 +17,15 @@ char *Group::DescriptionString(void) { return ret; } -void Request::AddParam(IdList *param, Entity *e, int index) { +hParam Request::AddParam(IdList *param, hParam hp) { Param pa; memset(&pa, 0, sizeof(pa)); - pa.h = e->param(index); + pa.h = hp; param->Add(&pa); + return hp; } void Request::Generate(IdList *entity, - IdList *point, IdList *param) { int points = 0; @@ -37,46 +37,50 @@ void Request::Generate(IdList *entity, Entity e; memset(&e, 0, sizeof(e)); - e.h = this->entity(0); - - bool shown = true; switch(type) { case Request::CSYS_2D: et = Entity::CSYS_2D; points = 1; params = 4; goto c; case Request::DATUM_POINT: - et = Entity::DATUM_POINT; points = 1; params = 0; goto c; + et = 0; points = 1; params = 0; goto c; case Request::LINE_SEGMENT: et = Entity::LINE_SEGMENT; points = 2; params = 0; goto c; c: { - // Common routines, for all the requests that generate a single - // entity that's defined by a simple combination of pts and params. - for(i = 0; i < params; i++) { - AddParam(param, &e, i); - } - for(i = 0; i < points; i++) { - Point pt; - memset(&pt, 0, sizeof(pt)); - pt.csys = csys; - pt.h = e.point(16 + 3*i); - if(csys.v == Entity::NO_CSYS.v) { - pt.type = Point::IN_FREE_SPACE; - // params for x y z - AddParam(param, &e, 16 + 3*i + 0); - AddParam(param, &e, 16 + 3*i + 1); - AddParam(param, &e, 16 + 3*i + 2); - } else { - pt.type = Point::IN_2D_CSYS; - // params for u v - AddParam(param, &e, 16 + 3*i + 0); - AddParam(param, &e, 16 + 3*i + 1); - } - point->Add(&pt); - } - + // Generate the entity that's specific to this request. e.type = et; - entity->Add(&e); + e.h = h.entity(0); + + // And generate entities for the points + for(i = 0; i < points; i++) { + Entity p; + memset(&p, 0, sizeof(p)); + p.csys = csys; + // points start from entity 1, except for datum point case + p.h = h.entity(i+(et ? 1 : 0)); + p.symbolic = true; + if(csys.v == Entity::NO_CSYS.v) { + p.type = Entity::POINT_IN_3D; + // params for x y z + p.param.h[0] = AddParam(param, h.param(16 + 3*i + 0)); + p.param.h[1] = AddParam(param, h.param(16 + 3*i + 1)); + p.param.h[2] = AddParam(param, h.param(16 + 3*i + 2)); + } else { + p.type = Entity::POINT_IN_2D; + // params for u v + p.param.h[0] = AddParam(param, h.param(16 + 3*i + 0)); + p.param.h[1] = AddParam(param, h.param(16 + 3*i + 1)); + } + entity->Add(&p); + e.assoc[i] = p.h; + } + // And generate any params not associated with the point that + // we happen to need. + for(i = 0; i < params; i++) { + e.param.h[i] = AddParam(param, h.param(i)); + } + + if(et) entity->Add(&e); break; } @@ -100,72 +104,4 @@ void Param::ForceTo(double v) { known = true; } -void Point::ForceTo(Vector p) { - switch(type) { - case IN_FREE_SPACE: - SS.GetParam(param(0))->ForceTo(p.x); - SS.GetParam(param(1))->ForceTo(p.y); - SS.GetParam(param(2))->ForceTo(p.z); - break; - - case IN_2D_CSYS: { - Entity *c = SS.GetEntity(csys); - Vector u, v; - c->Get2dCsysBasisVectors(&u, &v); - SS.GetParam(param(0))->ForceTo(p.Dot(u)); - SS.GetParam(param(1))->ForceTo(p.Dot(v)); - break; - } - - default: - oops(); - } -} - -Vector Point::GetCoords(void) { - Vector p; - switch(type) { - case IN_FREE_SPACE: - p.x = SS.GetParam(param(0))->val; - p.y = SS.GetParam(param(1))->val; - p.z = SS.GetParam(param(2))->val; - break; - - case IN_2D_CSYS: { - Entity *c = SS.GetEntity(csys); - Vector u, v; - c->Get2dCsysBasisVectors(&u, &v); - p = u.ScaledBy(SS.GetParam(param(0))->val); - p = p.Plus(v.ScaledBy(SS.GetParam(param(1))->val)); - break; - } - - default: - oops(); - } - - return p; -} - -void Point::Draw(void) { - Vector v = GetCoords(); - - double s = 4; - Vector r = SS.GW.projRight.ScaledBy(4/SS.GW.scale); - Vector d = SS.GW.projUp.ScaledBy(4/SS.GW.scale); - - glBegin(GL_QUADS); - glxVertex3v(v.Plus (r).Plus (d)); - glxVertex3v(v.Plus (r).Minus(d)); - glxVertex3v(v.Minus(r).Minus(d)); - glxVertex3v(v.Minus(r).Plus (d)); - glEnd(); -} - -double Point::GetDistance(Point2d mp) { - Vector v = GetCoords(); - Point2d pp = SS.GW.ProjectPoint(v); - - return pp.DistanceTo(mp); -} diff --git a/sketch.h b/sketch.h index 5867872..a0a005e 100644 --- a/sketch.h +++ b/sketch.h @@ -6,11 +6,9 @@ class hGroup; class hRequest; class hEntity; class hParam; -class hPoint; class Entity; class Param; -class Point; class hEquation; class Equation; @@ -19,41 +17,32 @@ class Equation; // some data structure in the sketch. class hGroup { public: - // bits 10: 0 -- group index + // bits 15: 0 -- group index DWORD v; }; class hRequest { public: - // bits 14: 0 -- request index (the high bits may be used as an import ID) + // bits 15: 0 -- request index DWORD v; inline hEntity entity(int i); + inline hParam param(int i); }; class hEntity { public: - // bits 9: 0 -- entity index - // 24:10 -- request index + // bits 15: 0 -- entity index + // 31:16 -- request index DWORD v; inline hRequest request(void); - inline hParam param(int i); - inline hPoint point(int i); }; class hParam { public: - // bits 6: 0 -- param index - // 16: 7 -- entity index - // 31:17 -- request index + // bits 15: 0 -- param index + // 31:16 -- request index DWORD v; -}; -class hPoint { - // bits 6: 0 -- point index - // 16: 7 -- entity index - // 31:17 -- request index -public: - DWORD v; - inline bool isFromReferences(void); + inline hRequest request(void); }; // A set of requests. Every request must have an associated group. @@ -94,13 +83,8 @@ public: NameStr name; - inline hEntity entity(int i) - { hEntity r; r.v = ((this->h.v) << 10) | i; return r; } - - void AddParam(IdList *param, Entity *e, int index); - void Generate(IdList *entity, - IdList *point, - IdList *param); + hParam AddParam(IdList *param, hParam hp); + void Generate(IdList *entity, IdList *param); char *DescriptionString(void); }; @@ -113,30 +97,46 @@ public: static const hEntity NO_CSYS; static const int CSYS_2D = 1000; - static const int DATUM_POINT = 1001; - static const int LINE_SEGMENT = 1010; + static const int POINT_IN_3D = 2000; + static const int POINT_IN_2D = 2001; + static const int LINE_SEGMENT = 3000; int type; - inline hRequest request(void) - { hRequest r; r.v = (this->h.v >> 10); return r; } - inline hParam param(int i) - { hParam r; r.v = ((this->h.v) << 7) | i; return r; } - inline hPoint point(int i) - { hPoint r; r.v = ((this->h.v) << 7) | i; return r; } + bool symbolic; + // The params are usually handles to the symbolic variables, but may + // also be constants + union { + hParam h[16]; + double v[16]; + } param; + // Associated entities, e.g. the endpoints for a line segment + hEntity assoc[16]; - char *DescriptionString(void); + hEntity csys; // or Entity::NO_CSYS + // Applies only for a CSYS_2D type void Get2dCsysBasisVectors(Vector *u, Vector *v); + bool IsPoint(void); + // Applies for any of the point types + void GetPointExprs(Expr **x, Expr **y, Expr **z); + Vector GetPointCoords(void); + void ForcePointTo(Vector v); + bool IsFromReferences(void); + + // Routines to draw and hit-test the representation of the entity + // on-screen. struct { bool drawing; Point2d mp; double dmin; - } dogd; // state for drawing or getting distance (for hit testing) + } dogd; void LineDrawOrGetDistance(Vector a, Vector b); void DrawOrGetDistance(void); void Draw(void); double GetDistance(Point2d mp); + + char *DescriptionString(void); }; class Param { @@ -150,53 +150,17 @@ public: void ForceTo(double v); }; -class Point { -public: - int tag; - // The point ID is equal to the initial param ID. - hPoint h; - - int type; - static const int IN_FREE_SPACE = 0; // three params, x y z - static const int IN_2D_CSYS = 1; // two params, u v, plus csys - - hEntity csys; - - inline hEntity entity(void) - { hEntity r; r.v = (h.v >> 7); return r; } - inline hParam param(int i) - { hParam r; r.v = h.v + i; return r; } - - // The point, in base coordinates. This may be a single parameter, or - // it may be a more complex expression if our point is locked in a - // 2d csys. - void GetExprs(Expr **x, Expr **y, Expr **z); - Vector GetCoords(void); - - void ForceTo(Vector v); - - void Draw(void); - double GetDistance(Point2d mp); -}; inline hEntity hRequest::entity(int i) - { hEntity r; r.v = (v << 10) | i; return r; } + { hEntity r; r.v = (v << 16) | i; return r; } +inline hParam hRequest::param(int i) + { hParam r; r.v = (v << 16) | i; return r; } inline hRequest hEntity::request(void) - { hRequest r; r.v = (v >> 10); return r; } -inline hParam hEntity::param(int i) - { hParam r; r.v = (v << 7) | i; return r; } -inline hPoint hEntity::point(int i) - { hPoint r; r.v = (v << 7) | i; return r; } - -inline bool hPoint::isFromReferences(void) { - DWORD d = v >> 17; - if(d == Request::HREQUEST_REFERENCE_XY.v) return true; - if(d == Request::HREQUEST_REFERENCE_YZ.v) return true; - if(d == Request::HREQUEST_REFERENCE_ZX.v) return true; - return false; -} + { hRequest r; r.v = (v >> 16); return r; } +inline hRequest hParam::request(void) + { hRequest r; r.v = (v >> 16); return r; } class hConstraint { @@ -223,9 +187,9 @@ public: // These are the parameters for the constraint. Expr *exprA; Expr *exprB; - hPoint ptA; - hPoint ptB; - hPoint ptC; + hEntity ptA; + hEntity ptB; + hEntity ptC; hEntity entityA; hEntity entityB; diff --git a/solvespace.cpp b/solvespace.cpp index c392450..8c29b75 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -8,7 +8,6 @@ void SolveSpace::Init(void) { group.Clear(); entity.Clear(); - point.Clear(); param.Clear(); // Our initial group, that contains the references. @@ -57,9 +56,8 @@ void SolveSpace::GenerateAll(void) { param.MoveSelfInto(&prev); entity.Clear(); - point.Clear(); for(i = 0; i < request.n; i++) { - request.elem[i].Generate(&entity, &point, ¶m); + request.elem[i].Generate(&entity, ¶m); } for(i = 0; i < param.n; i++) { @@ -84,17 +82,15 @@ void SolveSpace::ForceReferences(void) { { Request::HREQUEST_REFERENCE_ZX, 0.5, -0.5, -0.5, -0.5, }, }; for(int i = 0; i < 3; i++) { - hEntity he; - he = request.FindById(Quat[i].hr)->entity(0); - Entity *e = entity.FindById(he); + hRequest hr = Quat[i].hr; // The origin for our coordinate system, always zero Vector v = Vector::MakeFrom(0, 0, 0); - point.FindById(e->point(16))->ForceTo(v); + GetEntity(hr.entity(1))->ForcePointTo(v); // The quaternion that defines the rotation, from the table. - param.FindById(e->param(0))->ForceTo(Quat[i].a); - param.FindById(e->param(1))->ForceTo(Quat[i].b); - param.FindById(e->param(2))->ForceTo(Quat[i].c); - param.FindById(e->param(3))->ForceTo(Quat[i].d); + GetParam(hr.param(0))->ForceTo(Quat[i].a); + GetParam(hr.param(1))->ForceTo(Quat[i].b); + GetParam(hr.param(2))->ForceTo(Quat[i].c); + GetParam(hr.param(3))->ForceTo(Quat[i].d); } } diff --git a/solvespace.h b/solvespace.h index d1a31a6..4f416f1 100644 --- a/solvespace.h +++ b/solvespace.h @@ -61,6 +61,9 @@ void glxVertex3v(Vector u); void glxWriteText(char *str); void glxTranslatev(Vector u); void glxOntoCsys(Vector u, Vector v); +void glxLockColorTo(double r, double g, double b); +void glxUnlockColor(void); +void glxColor(double r, double g, double b); #define arraylen(x) (sizeof((x))/sizeof((x)[0])) @@ -83,7 +86,6 @@ public: // These lists are generated automatically when we solve the sketch. IdList entity; - IdList point; IdList param; inline Constraint *GetConstraint(hConstraint h) @@ -91,7 +93,6 @@ public: inline Request *GetRequest(hRequest h) { return request.FindById(h); } inline Entity *GetEntity (hEntity h) { return entity. FindById(h); } inline Param *GetParam (hParam h) { return param. FindById(h); } - inline Point *GetPoint (hPoint h) { return point. FindById(h); } hGroup activeGroup; diff --git a/ui.h b/ui.h index fc6d34d..53d37f6 100644 --- a/ui.h +++ b/ui.h @@ -137,7 +137,7 @@ public: // Operations that must be completed by doing something with the mouse // are noted here. static const int PENDING_OPERATION_DRAGGING_POINT = 0x0f000000; - hPoint pendingPoint; + hEntity pendingPoint; int pendingOperation; char *pendingDescription; hRequest AddRequest(int type); @@ -146,7 +146,6 @@ public: // The current selection. class Selection { public: - hPoint point; hEntity entity; hConstraint constraint; @@ -162,7 +161,7 @@ public: void HitTestMakeSelection(Point2d mp, Selection *dest); void ClearSelection(void); struct { - hPoint point[MAX_SELECTED]; + hEntity point[MAX_SELECTED]; hEntity entity[MAX_SELECTED]; int points; int entities; @@ -182,7 +181,7 @@ public: static void ToggleAnyDatumShown(int link, DWORD v); void UpdateDraggedPoint(Vector *pos, double mx, double my); - void UpdateDraggedHPoint(hPoint hp, double mx, double my); + void UpdateDraggedEntity(hEntity hp, double mx, double my); // These are called by the platform-specific code. void Paint(int w, int h);