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);