Big structural change; eliminate the Point type in SolveSpace. The
points are now entities like any others; so a line segment request will generate three entities, the line segment and its endpoints. I think that's cleaner. When I do step and repeats (and imports, and other similar), I'll need a consistent way to assign those entity ids. That assignment must not change if the sketch is edited. I don't have a clean way to do that; best thought right now is to keep a record of what maps have been used previously, and not pick a new map as long as it's possible to use one that was used previously. This all means that more crap gets pushed in to the Entity structure, so that they can keep track of what solver variables define them. Still seems better, though. I'm closer to ready to start solving. [git-p4: depot-paths = "//depot/solvespace/": change = 1673]solver
parent
0d3217c0df
commit
cc03fe40aa
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
2
dsc.h
2
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;
|
||||
|
|
107
entity.cpp
107
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);
|
||||
|
@ -47,10 +107,40 @@ double Entity::GetDistance(Point2d mp) {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
1
expr.h
1
expr.h
|
@ -45,7 +45,6 @@ public:
|
|||
double v;
|
||||
hParam parh;
|
||||
Param *parp;
|
||||
hPoint point;
|
||||
hEntity entity;
|
||||
|
||||
// For use while parsing
|
||||
|
|
8
file.cpp
8
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);
|
||||
|
|
21
glhelper.cpp
21
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
124
sketch.cpp
124
sketch.cpp
|
@ -17,15 +17,15 @@ char *Group::DescriptionString(void) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Request::AddParam(IdList<Param,hParam> *param, Entity *e, int index) {
|
||||
hParam Request::AddParam(IdList<Param,hParam> *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,hEntity> *entity,
|
||||
IdList<Point,hPoint> *point,
|
||||
IdList<Param,hParam> *param)
|
||||
{
|
||||
int points = 0;
|
||||
|
@ -37,46 +37,50 @@ void Request::Generate(IdList<Entity,hEntity> *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);
|
||||
}
|
||||
// Generate the entity that's specific to this request.
|
||||
e.type = et;
|
||||
e.h = h.entity(0);
|
||||
|
||||
// And generate entities for the points
|
||||
for(i = 0; i < points; i++) {
|
||||
Point pt;
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.csys = csys;
|
||||
pt.h = e.point(16 + 3*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) {
|
||||
pt.type = Point::IN_FREE_SPACE;
|
||||
p.type = Entity::POINT_IN_3D;
|
||||
// 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);
|
||||
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 {
|
||||
pt.type = Point::IN_2D_CSYS;
|
||||
p.type = Entity::POINT_IN_2D;
|
||||
// params for u v
|
||||
AddParam(param, &e, 16 + 3*i + 0);
|
||||
AddParam(param, &e, 16 + 3*i + 1);
|
||||
p.param.h[0] = AddParam(param, h.param(16 + 3*i + 0));
|
||||
p.param.h[1] = AddParam(param, h.param(16 + 3*i + 1));
|
||||
}
|
||||
point->Add(&pt);
|
||||
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));
|
||||
}
|
||||
|
||||
e.type = et;
|
||||
entity->Add(&e);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
126
sketch.h
126
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,hParam> *param, Entity *e, int index);
|
||||
void Generate(IdList<Entity,hEntity> *entity,
|
||||
IdList<Point,hPoint> *point,
|
||||
IdList<Param,hParam> *param);
|
||||
hParam AddParam(IdList<Param,hParam> *param, hParam hp);
|
||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,hEntity> entity;
|
||||
IdList<Point,hPoint> point;
|
||||
IdList<Param,hParam> 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;
|
||||
|
||||
|
|
7
ui.h
7
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);
|
||||
|
|
Loading…
Reference in New Issue