Add double-sided extrudes, and user interface for that. Also put

the coordinate system (x, y, z normal vectors) in the bottom left
corner of the screen at all times, and hide group-created
workplanes except when that group is active, and activate that
workplane when the group is activated.

[git-p4: depot-paths = "//depot/solvespace/": change = 1726]
This commit is contained in:
Jonathan Westhues 2008-05-17 00:02:39 -08:00
parent 3cdbbb83b1
commit 749e2a0149
9 changed files with 182 additions and 83 deletions

View File

@ -9,7 +9,7 @@ char *Constraint::DescriptionString(void) {
hConstraint Constraint::AddConstraint(Constraint *c) { hConstraint Constraint::AddConstraint(Constraint *c) {
SS.constraint.AddAndAssignId(c); SS.constraint.AddAndAssignId(c);
SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
return c->h; return c->h;
} }

View File

@ -332,7 +332,7 @@ void Entity::PointForceTo(Vector p) {
} }
case POINT_N_TRANS: { case POINT_N_TRANS: {
Vector trans = p.Minus(numPoint); Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
SS.GetParam(param[0])->val = trans.x; SS.GetParam(param[0])->val = trans.x;
SS.GetParam(param[1])->val = trans.y; SS.GetParam(param[1])->val = trans.y;
SS.GetParam(param[2])->val = trans.z; SS.GetParam(param[2])->val = trans.z;
@ -379,9 +379,9 @@ Vector Entity::PointGetNum(void) {
case POINT_N_TRANS: { case POINT_N_TRANS: {
p = numPoint; p = numPoint;
p.x += SS.GetParam(param[0])->val; p.x += timesApplied * SS.GetParam(param[0])->val;
p.y += SS.GetParam(param[1])->val; p.y += timesApplied * SS.GetParam(param[1])->val;
p.z += SS.GetParam(param[2])->val; p.z += timesApplied * SS.GetParam(param[2])->val;
break; break;
} }
@ -432,7 +432,7 @@ ExprVector Entity::PointGetExprs(void) {
trans.x = Expr::FromParam(param[0]); trans.x = Expr::FromParam(param[0]);
trans.y = Expr::FromParam(param[1]); trans.y = Expr::FromParam(param[1]);
trans.z = Expr::FromParam(param[2]); trans.z = Expr::FromParam(param[2]);
r = orig.Plus(trans); r = orig.Plus(trans.ScaledBy(Expr::FromConstant(timesApplied)));
break; break;
} }
case POINT_N_ROT_TRANS: { case POINT_N_ROT_TRANS: {
@ -619,27 +619,47 @@ void Entity::DrawOrGetDistance(int order) {
if(order >= 0 && order != 2) break; if(order >= 0 && order != 2) break;
if(!SS.GW.showNormals) break; if(!SS.GW.showNormals) break;
hRequest hr = h.request(); int i;
double f = 0.5; for(i = 0; i < 2; i++) {
if(hr.v == Request::HREQUEST_REFERENCE_XY.v) { hRequest hr = h.request();
glxColor3d(0, 0, f); double f = (i == 0 ? 0.4 : 1);
} else if(hr.v == Request::HREQUEST_REFERENCE_YZ.v) { if(hr.v == Request::HREQUEST_REFERENCE_XY.v) {
glxColor3d(f, 0, 0); glxColor3d(0, 0, f);
} else if(hr.v == Request::HREQUEST_REFERENCE_ZX.v) { } else if(hr.v == Request::HREQUEST_REFERENCE_YZ.v) {
glxColor3d(0, f, 0); glxColor3d(f, 0, 0);
} else { } else if(hr.v == Request::HREQUEST_REFERENCE_ZX.v) {
glxColor3d(0, 0.4, 0.4); glxColor3d(0, f, 0);
} } else {
Quaternion q = NormalGetNum(); glxColor3d(0, 0.4, 0.4);
Vector tail = SS.GetEntity(point[0])->PointGetNum(); if(i > 0) break;
Vector v = (q.RotationN()).WithMagnitude(50/SS.GW.scale); }
Vector tip = tail.Plus(v);
LineDrawOrGetDistance(tail, tip);
v = v.WithMagnitude(12/SS.GW.scale); Quaternion q = NormalGetNum();
Vector axis = q.RotationV(); Vector tail;
LineDrawOrGetDistance(tip, tip.Minus(v.RotatedAbout(axis, 0.6))); if(i == 0) {
LineDrawOrGetDistance(tip, tip.Minus(v.RotatedAbout(axis, -0.6))); tail = SS.GetEntity(point[0])->PointGetNum();
} else {
// Draw an extra copy of the x, y, and z axes, that's
// always in the corner of the view and at the front.
// So those are always available, perhaps useful.
double s = SS.GW.scale;
double h = 60 - SS.GW.height/2;
double w = 60 - SS.GW.width/2;
Vector gn = SS.GW.projRight.Cross(SS.GW.projUp);
tail = SS.GW.projRight.ScaledBy(w/s).Plus(
SS.GW.projUp. ScaledBy(h/s)).Plus(
gn.ScaledBy(-4*w/s)).Minus(SS.GW.offset);
}
Vector v = (q.RotationN()).WithMagnitude(50/SS.GW.scale);
Vector tip = tail.Plus(v);
LineDrawOrGetDistance(tail, tip);
v = v.WithMagnitude(12/SS.GW.scale);
Vector axis = q.RotationV();
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis, 0.6)));
LineDrawOrGetDistance(tip,tip.Minus(v.RotatedAbout(axis,-0.6)));
}
break; break;
} }
@ -652,6 +672,12 @@ void Entity::DrawOrGetDistance(int order) {
if(order >= 0 && order != 0) break; if(order >= 0 && order != 0) break;
if(!SS.GW.showWorkplanes) break; if(!SS.GW.showWorkplanes) break;
if((!h.isFromRequest()) && (h.group().v != SS.GW.activeGroup.v)) {
// Workplanes that are automatically created by an in-wrkpl
// drawing group appear only when that group is active.
break;
}
Vector p; Vector p;
p = SS.GetEntity(point[0])->PointGetNum(); p = SS.GetEntity(point[0])->PointGetNum();

View File

@ -50,7 +50,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
{ 'g', "Group.name", 'N', &(SS.sv.g.name) }, { 'g', "Group.name", 'N', &(SS.sv.g.name) },
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) }, { 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) }, { 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
{ 'g', "Group.wrkpl.type", 'd', &(SS.sv.g.wrkpl.type) }, { 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
{ 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) }, { 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) },
{ 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) }, { 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) },
{ 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) }, { 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) },

View File

@ -267,6 +267,10 @@ void GraphicsWindow::EnsureValidActives(void) {
if(change) SS.TW.Show(); if(change) SS.TW.Show();
} }
void GraphicsWindow::GeneratePerSolving(void) {
SS.GenerateAll(solving == SOLVE_ALWAYS);
}
void GraphicsWindow::MenuEdit(int id) { void GraphicsWindow::MenuEdit(int id) {
switch(id) { switch(id) {
case MNU_UNSELECT_ALL: case MNU_UNSELECT_ALL:
@ -302,7 +306,7 @@ void GraphicsWindow::MenuEdit(int id) {
SS.GW.hover.Clear(); SS.GW.hover.Clear();
// And regenerate to get rid of what it generates, plus anything // And regenerate to get rid of what it generates, plus anything
// that references it (since the regen code checks for that). // that references it (since the regen code checks for that).
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
SS.TW.Show(); SS.TW.Show();
break; break;
@ -365,7 +369,7 @@ c:
r->construction = !(r->construction); r->construction = !(r->construction);
} }
SS.GW.ClearSelection(); SS.GW.ClearSelection();
SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
break; break;
} }
@ -607,7 +611,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
default: oops(); default: oops();
} }
SS.GenerateAll(solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
havePainted = false; havePainted = false;
} }
@ -958,7 +962,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break; break;
} }
} }
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
SS.TW.Show(); SS.TW.Show();
InvalidateGraphics(); InvalidateGraphics();
@ -998,7 +1002,7 @@ void GraphicsWindow::EditControlDone(char *s) {
Expr::FreeKeep(&(c->exprA)); Expr::FreeKeep(&(c->exprA));
c->exprA = e->DeepCopyKeep(); c->exprA = e->DeepCopyKeep();
HideGraphicsEditControl(); HideGraphicsEditControl();
SS.GenerateAll(solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
} else { } else {
Error("Not a valid number or expression: '%s'", s); Error("Not a valid number or expression: '%s'", s);
} }
@ -1030,7 +1034,7 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) {
bool *vb = (bool *)v; bool *vb = (bool *)v;
*vb = !*vb; *vb = !*vb;
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
InvalidateGraphics(); InvalidateGraphics();
SS.TW.Show(); SS.TW.Show();
} }
@ -1041,7 +1045,7 @@ void GraphicsWindow::ToggleAnyDatumShown(int link, DWORD v) {
SS.GW.showNormals = t; SS.GW.showNormals = t;
SS.GW.showPoints = t; SS.GW.showPoints = t;
SS.GenerateAll(SS.GW.solving == SOLVE_ALWAYS); SS.GW.GeneratePerSolving();
InvalidateGraphics(); InvalidateGraphics();
SS.TW.Show(); SS.TW.Show();
} }
@ -1091,6 +1095,9 @@ void GraphicsWindow::Paint(int w, int h) {
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
// At the same depth, we want later lines drawn over earlier.
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0); glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

View File

@ -37,7 +37,7 @@ void Group::MenuGroup(int id) {
g.type = DRAWING_WORKPLANE; g.type = DRAWING_WORKPLANE;
g.name.strcpy("draw-in-plane"); g.name.strcpy("draw-in-plane");
if(gs.points == 1 && gs.n == 1) { if(gs.points == 1 && gs.n == 1) {
g.wrkpl.type = WORKPLANE_BY_POINT_ORTHO; g.subtype = WORKPLANE_BY_POINT_ORTHO;
Vector u = SS.GW.projRight, v = SS.GW.projUp; Vector u = SS.GW.projRight, v = SS.GW.projUp;
u = u.ClosestOrtho(); u = u.ClosestOrtho();
@ -47,7 +47,7 @@ void Group::MenuGroup(int id) {
g.wrkpl.q = Quaternion::MakeFrom(u, v); g.wrkpl.q = Quaternion::MakeFrom(u, v);
g.wrkpl.origin = gs.point[0]; g.wrkpl.origin = gs.point[0];
} else if(gs.points == 1 && gs.lineSegments == 2 && gs.n == 3) { } else if(gs.points == 1 && gs.lineSegments == 2 && gs.n == 3) {
g.wrkpl.type = WORKPLANE_BY_LINE_SEGMENTS; g.subtype = WORKPLANE_BY_LINE_SEGMENTS;
g.wrkpl.origin = gs.point[0]; g.wrkpl.origin = gs.point[0];
g.wrkpl.entityB = gs.entity[0]; g.wrkpl.entityB = gs.entity[0];
@ -75,6 +75,7 @@ void Group::MenuGroup(int id) {
g.type = EXTRUDE; g.type = EXTRUDE;
g.opA = SS.GW.activeGroup; g.opA = SS.GW.activeGroup;
g.wrkpl.entityB = SS.GW.activeWorkplane; g.wrkpl.entityB = SS.GW.activeWorkplane;
g.subtype = EXTRUDE_TWO_SIDED;
g.name.strcpy("extrude"); g.name.strcpy("extrude");
break; break;
@ -122,7 +123,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
case DRAWING_WORKPLANE: { case DRAWING_WORKPLANE: {
Quaternion q; Quaternion q;
if(wrkpl.type == WORKPLANE_BY_LINE_SEGMENTS) { if(subtype == WORKPLANE_BY_LINE_SEGMENTS) {
Vector u = SS.GetEntity(wrkpl.entityB)->VectorGetNum(); Vector u = SS.GetEntity(wrkpl.entityB)->VectorGetNum();
Vector v = SS.GetEntity(wrkpl.entityC)->VectorGetNum(); Vector v = SS.GetEntity(wrkpl.entityC)->VectorGetNum();
u = u.WithMagnitude(1); u = u.WithMagnitude(1);
@ -133,7 +134,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
if(wrkpl.negateU) u = u.ScaledBy(-1); if(wrkpl.negateU) u = u.ScaledBy(-1);
if(wrkpl.negateV) v = v.ScaledBy(-1); if(wrkpl.negateV) v = v.ScaledBy(-1);
q = Quaternion::MakeFrom(u, v); q = Quaternion::MakeFrom(u, v);
} else if(wrkpl.type == WORKPLANE_BY_POINT_ORTHO) { } else if(subtype == WORKPLANE_BY_POINT_ORTHO) {
// Already given, numerically. // Already given, numerically.
q = wrkpl.q; q = wrkpl.q;
} else oops(); } else oops();
@ -170,14 +171,28 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
AddParam(param, h.param(0), gn.x); AddParam(param, h.param(0), gn.x);
AddParam(param, h.param(1), gn.y); AddParam(param, h.param(1), gn.y);
AddParam(param, h.param(2), gn.z); AddParam(param, h.param(2), gn.z);
int ai, af;
if(subtype == EXTRUDE_ONE_SIDED) {
ai = 0; af = 1;
} else if(subtype == EXTRUDE_TWO_SIDED) {
ai = -1; af = 1;
} else oops();
for(i = 0; i < entity->n; i++) { for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]); Entity *e = &(entity->elem[i]);
if(e->group.v != opA.v) continue; if(e->group.v != opA.v) continue;
CopyEntity(e->h, 0, hEntity he = e->h; e = NULL;
// As soon as I call CopyEntity, e may become invalid! That
// adds entities, which may cause a realloc.
CopyEntity(he, ai,
h.param(0), h.param(1), h.param(2), h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true, true); true);
CopyEntity(he, af,
h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true);
MakeExtrusionLines(he, ai, af);
} }
break; break;
@ -199,7 +214,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
CopyEntity(e->h, 0, CopyEntity(e->h, 0,
h.param(0), h.param(1), h.param(2), h.param(0), h.param(1), h.param(2),
h.param(3), h.param(4), h.param(5), h.param(6), h.param(3), h.param(4), h.param(5), h.param(6),
false, false); false);
} }
break; break;
@ -255,9 +270,24 @@ hEntity Group::Remap(hEntity in, int copyNumber) {
return h.entity(em.h.v); return h.entity(em.h.v);
} }
void Group::MakeExtrusionLines(hEntity in, int ai, int af) {
Entity *ep = SS.GetEntity(in);
if(!(ep->IsPoint())) return;
Entity en;
memset(&en, 0, sizeof(en));
en.point[0] = Remap(ep->h, ai);
en.point[1] = Remap(ep->h, af);
en.group = h;
en.h = Remap(ep->h, 10);
en.type = Entity::LINE_SEGMENT;
// And then this line segment gets added
SS.entity.Add(&en);
}
void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz, void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
hParam qw, hParam qvx, hParam qvy, hParam qvz, hParam qw, hParam qvx, hParam qvy, hParam qvz,
bool transOnly, bool isExtrusion) bool transOnly)
{ {
Entity *ep = SS.GetEntity(in); Entity *ep = SS.GetEntity(in);
@ -307,7 +337,6 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
en.param[0] = dx; en.param[0] = dx;
en.param[1] = dy; en.param[1] = dy;
en.param[2] = dz; en.param[2] = dz;
en.numPoint = ep->PointGetNum();
} else { } else {
en.type = Entity::POINT_N_ROT_TRANS; en.type = Entity::POINT_N_ROT_TRANS;
en.param[0] = dx; en.param[0] = dx;
@ -317,25 +346,9 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
en.param[4] = qvx; en.param[4] = qvx;
en.param[5] = qvy; en.param[5] = qvy;
en.param[6] = qvz; en.param[6] = qvz;
en.numPoint = ep->PointGetNum();
}
if(isExtrusion) {
if(a != 0) oops();
SS.entity.Add(&en);
// Any operation on these lists may break existing pointers!
ep = SS.GetEntity(in);
hEntity np = en.h;
memset(&en, 0, sizeof(en));
en.point[0] = ep->h;
en.point[1] = np;
en.group = h;
en.h = Remap(ep->h, 1);
en.type = Entity::LINE_SEGMENT;
// And then this line segment gets added
} }
en.numPoint = ep->PointGetNum();
en.timesApplied = a;
break; break;
case Entity::NORMAL_N_COPY: case Entity::NORMAL_N_COPY:
@ -344,16 +357,16 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
case Entity::NORMAL_IN_2D: case Entity::NORMAL_IN_2D:
if(transOnly) { if(transOnly) {
en.type = Entity::NORMAL_N_COPY; en.type = Entity::NORMAL_N_COPY;
en.numNormal = ep->NormalGetNum();
} else { } else {
en.type = Entity::NORMAL_N_ROT; en.type = Entity::NORMAL_N_ROT;
en.numNormal = ep->NormalGetNum();
en.param[0] = qw; en.param[0] = qw;
en.param[1] = qvx; en.param[1] = qvx;
en.param[2] = qvy; en.param[2] = qvy;
en.param[3] = qvz; en.param[3] = qvz;
} }
en.numNormal = ep->NormalGetNum();
en.point[0] = Remap(ep->point[0], a); en.point[0] = Remap(ep->point[0], a);
en.timesApplied = a;
break; break;
case Entity::DISTANCE_N_COPY: case Entity::DISTANCE_N_COPY:
@ -400,12 +413,24 @@ void Group::MakePolygons(void) {
translate.x = SS.GetParam(h.param(0))->val; translate.x = SS.GetParam(h.param(0))->val;
translate.y = SS.GetParam(h.param(1))->val; translate.y = SS.GetParam(h.param(1))->val;
translate.z = SS.GetParam(h.param(2))->val; translate.z = SS.GetParam(h.param(2))->val;
Vector t0, dt;
if(subtype == EXTRUDE_ONE_SIDED) {
t0 = Vector::MakeFrom(0, 0, 0); dt = translate;
} else {
t0 = translate.ScaledBy(-1); dt = translate.ScaledBy(2);
}
// Get the source polygon to extrude, and break it down to edges
edges.l.Clear(); edges.l.Clear();
Group *src = SS.GetGroup(opA); Group *src = SS.GetGroup(opA);
if(src->faces.n != 1) return; if(src->faces.n != 1) return;
(src->faces.elem[0]).MakeEdgesInto(&edges); (src->faces.elem[0]).MakeEdgesInto(&edges);
for(i = 0; i < edges.l.n; i++) {
SEdge *edge = &(edges.l.elem[i]);
edge->a = (edge->a).Plus(t0);
edge->b = (edge->b).Plus(t0);
}
SPolygon poly; SPolygon poly;
SEdge error; SEdge error;
@ -419,7 +444,6 @@ void Group::MakePolygons(void) {
} }
poly.normal = n; poly.normal = n;
poly.FixContourDirections(); poly.FixContourDirections();
poly.FixContourDirections();
faces.Add(&poly); faces.Add(&poly);
// Regenerate the edges, with the contour directions fixed up. // Regenerate the edges, with the contour directions fixed up.
@ -434,14 +458,14 @@ void Group::MakePolygons(void) {
poly.AddEmptyContour(); poly.AddEmptyContour();
poly.AddPoint(edge->a); poly.AddPoint(edge->a);
poly.AddPoint(edge->b); poly.AddPoint(edge->b);
poly.AddPoint((edge->b).Plus(translate)); poly.AddPoint((edge->b).Plus(dt));
poly.AddPoint((edge->a).Plus(translate)); poly.AddPoint((edge->a).Plus(dt));
poly.AddPoint(edge->a); poly.AddPoint(edge->a);
poly.normal = ((edge->a).Minus(edge->b).Cross(n)).WithMagnitude(1); poly.normal = ((edge->a).Minus(edge->b).Cross(n)).WithMagnitude(1);
faces.Add(&poly); faces.Add(&poly);
edge->a = (edge->a).Plus(translate); edge->a = (edge->a).Plus(dt);
edge->b = (edge->b).Plus(translate); edge->b = (edge->b).Plus(dt);
} }
// The top // The top

View File

@ -92,8 +92,11 @@ public:
static const int WORKPLANE_BY_POINT_ORTHO = 6000; static const int WORKPLANE_BY_POINT_ORTHO = 6000;
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001; static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
static const int EXTRUDE_ONE_SIDED = 7000;
static const int EXTRUDE_TWO_SIDED = 7001;
int subtype;
struct { struct {
int type;
Quaternion q; Quaternion q;
hEntity origin; hEntity origin;
hEntity entityB; hEntity entityB;
@ -121,9 +124,10 @@ public:
// mapping list. // mapping list.
IdList<EntityMap,EntityId> remap; IdList<EntityMap,EntityId> remap;
hEntity Remap(hEntity in, int copyNumber); hEntity Remap(hEntity in, int copyNumber);
void MakeExtrusionLines(hEntity in, int ai, int af);
void CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz, void CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
hParam qw, hParam qvx, hParam qvy, hParam qvz, hParam qw, hParam qvx, hParam qvy, hParam qvz,
bool transOnly, bool isExtrusion); bool transOnly);
void GenerateEquations(IdList<Equation,hEquation> *l); void GenerateEquations(IdList<Equation,hEquation> *l);

View File

@ -210,7 +210,6 @@ void TextWindow::ScreenNavigation(int link, DWORD v) {
SS.TW.OneScreenForwardTo(-1); SS.TW.OneScreenForwardTo(-1);
break; break;
} }
SS.TW.Show();
} }
void TextWindow::ShowHeader(void) { void TextWindow::ShowHeader(void) {
ClearScreen(); ClearScreen();
@ -262,25 +261,37 @@ hs(SS.GW.showHdnLines), (DWORD)(&SS.GW.showHdnLines), &(SS.GW.ToggleBool)
void TextWindow::ScreenSelectGroup(int link, DWORD v) { void TextWindow::ScreenSelectGroup(int link, DWORD v) {
SS.TW.OneScreenForwardTo(SCREEN_GROUP_INFO); SS.TW.OneScreenForwardTo(SCREEN_GROUP_INFO);
SS.TW.shown->group.v = v; SS.TW.shown->group.v = v;
SS.TW.Show();
} }
void TextWindow::ScreenToggleGroupShown(int link, DWORD v) { void TextWindow::ScreenToggleGroupShown(int link, DWORD v) {
hGroup hg = { v }; hGroup hg = { v };
Group *g = SS.GetGroup(hg); Group *g = SS.GetGroup(hg);
g->visible = !(g->visible); g->visible = !(g->visible);
}
void TextWindow::ScreenShowGroupsSpecial(int link, DWORD v) {
int i;
bool before = true;
for(i = 0; i < SS.group.n; i++) {
Group *g = &(SS.group.elem[i]);
InvalidateGraphics(); if(g->h.v == SS.GW.activeGroup.v) {
SS.TW.Show(); before = false;
} else if(before && link == 's') {
g->visible = true;
} else if(!before && link == 'h') {
g->visible = false;
}
}
} }
void TextWindow::ScreenActivateGroup(int link, DWORD v) { void TextWindow::ScreenActivateGroup(int link, DWORD v) {
hGroup hg = { v }; hGroup hg = { v };
Group *g = SS.GetGroup(hg); Group *g = SS.GetGroup(hg);
g->visible = true; g->visible = true;
SS.GW.activeGroup.v = v; SS.GW.activeGroup.v = v;
if(g->type == Group::DRAWING_WORKPLANE) {
InvalidateGraphics(); // If we're activating an in-workplane drawing, then activate that
SS.TW.Show(); // workplane too.
SS.GW.activeWorkplane = g->h.entity(0);
}
} }
void TextWindow::ShowListOfGroups(void) { void TextWindow::ShowListOfGroups(void) {
Printf(true, "%Ftactive show group-name%E"); Printf(true, "%Ftactive show group-name%E");
@ -309,20 +320,30 @@ void TextWindow::ShowListOfGroups(void) {
// Link to a screen that gives more details on the group // Link to a screen that gives more details on the group
g->h.v, (&TextWindow::ScreenSelectGroup), s); g->h.v, (&TextWindow::ScreenSelectGroup), s);
} }
Printf(true, " %Fl%Ls%fshow all groups before active%E",
&(TextWindow::ScreenShowGroupsSpecial));
Printf(false, " %Fl%Lh%fhide all groups after active%E",
&(TextWindow::ScreenShowGroupsSpecial));
} }
void TextWindow::ScreenSelectConstraint(int link, DWORD v) { void TextWindow::ScreenSelectConstraint(int link, DWORD v) {
SS.TW.OneScreenForwardTo(SCREEN_CONSTRAINT_INFO); SS.TW.OneScreenForwardTo(SCREEN_CONSTRAINT_INFO);
SS.TW.shown->constraint.v = v; SS.TW.shown->constraint.v = v;
SS.TW.Show();
} }
void TextWindow::ScreenSelectRequest(int link, DWORD v) { void TextWindow::ScreenSelectRequest(int link, DWORD v) {
SS.TW.OneScreenForwardTo(SCREEN_REQUEST_INFO); SS.TW.OneScreenForwardTo(SCREEN_REQUEST_INFO);
SS.TW.shown->request.v = v; SS.TW.shown->request.v = v;
}
SS.TW.Show(); void TextWindow::ScreenChangeExtrudeSides(int link, DWORD v) {
Group *g = SS.GetGroup(SS.TW.shown->group);
if(g->subtype == Group::EXTRUDE_ONE_SIDED) {
g->subtype = Group::EXTRUDE_TWO_SIDED;
} else {
g->subtype = Group::EXTRUDE_ONE_SIDED;
}
SS.GW.GeneratePerSolving();
} }
void TextWindow::ShowGroupInfo(void) { void TextWindow::ShowGroupInfo(void) {
Group *g = SS.group.FindById(shown->group); Group *g = SS.group.FindById(shown->group);
@ -334,7 +355,18 @@ void TextWindow::ShowGroupInfo(void) {
} else { } else {
s = ""; s = "";
} }
Printf(true, "%Ft%sgroup %E%s", s, g->DescriptionString()); Printf(true, "%Ft%sGROUP %E%s", s, g->DescriptionString());
if(g->type == Group::EXTRUDE) {
bool one = (g->subtype == Group::EXTRUDE_ONE_SIDED);
Printf(true, "%FtEXTRUDE%E one-sided: %Fh%f%Ll%s%E%Fs%s%E",
&TextWindow::ScreenChangeExtrudeSides,
(one ? "" : "no"), (one ? "yes" : ""));
Printf(false, " two-sided: %Fh%f%Ll%s%E%Fs%s%E",
&TextWindow::ScreenChangeExtrudeSides,
(!one ? "" : "no"), (!one ? "yes" : ""));
}
Printf(true, "%Ftrequests in group"); Printf(true, "%Ftrequests in group");
int i, a = 0; int i, a = 0;

4
ui.h
View File

@ -69,9 +69,12 @@ public:
static void ScreenSelectGroup(int link, DWORD v); static void ScreenSelectGroup(int link, DWORD v);
static void ScreenActivateGroup(int link, DWORD v); static void ScreenActivateGroup(int link, DWORD v);
static void ScreenToggleGroupShown(int link, DWORD v); static void ScreenToggleGroupShown(int link, DWORD v);
static void ScreenShowGroupsSpecial(int link, DWORD v);
static void ScreenSelectRequest(int link, DWORD v); static void ScreenSelectRequest(int link, DWORD v);
static void ScreenSelectConstraint(int link, DWORD v); static void ScreenSelectConstraint(int link, DWORD v);
static void ScreenChangeExtrudeSides(int link, DWORD v);
static void ScreenNavigation(int link, DWORD v); static void ScreenNavigation(int link, DWORD v);
}; };
@ -254,6 +257,7 @@ public:
static const int DONT_SOLVE = 0; static const int DONT_SOLVE = 0;
static const int SOLVE_ALWAYS = 1; static const int SOLVE_ALWAYS = 1;
int solving; int solving;
void GeneratePerSolving(void);
void UpdateDraggedNum(Vector *pos, double mx, double my); void UpdateDraggedNum(Vector *pos, double mx, double my);
void UpdateDraggedPoint(hEntity hp, double mx, double my); void UpdateDraggedPoint(hEntity hp, double mx, double my);

View File

@ -318,6 +318,8 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
SS.TW.meta[r][c].link, SS.TW.meta[r][c].link,
SS.TW.meta[r][c].data SS.TW.meta[r][c].data
); );
SS.TW.Show();
InvalidateGraphics();
} }
} }
break; break;