Stipple the selected/hovered faces, instead of drawing them in

solid red or yellow. And add user interface to `hide' the faces
(i.e., to make them unselectable), defaulting to hidden in
everything except extrudes or imports.

[git-p4: depot-paths = "//depot/solvespace/": change = 1768]
This commit is contained in:
Jonathan Westhues 2008-06-01 21:38:12 -08:00
parent 1f70494ce9
commit a084b32064
6 changed files with 111 additions and 12 deletions

View File

@ -111,6 +111,53 @@ void glxColor4d(double r, double g, double b, double a)
if(!ColorLocked) glColor4d(r, g, b, a);
}
static void Stipple(BOOL forSel)
{
static BOOL Init;
const int BYTES = (32*32)/8;
static GLubyte HoverMask[BYTES];
static GLubyte SelMask[BYTES];
if(!Init) {
int x, y;
for(x = 0; x < 32; x++) {
for(y = 0; y < 32; y++) {
int i = y*4 + x/8, b = x % 8;
int ym = y % 4, xm = x % 4;
for(int k = 0; k < 2; k++) {
if(xm >= 1 && xm <= 2 && ym >= 1 && ym <= 2) {
(k == 0 ? SelMask : HoverMask)[i] |= (0x80 >> b);
}
ym = (ym + 2) % 4; xm = (xm + 2) % 4;
}
}
}
Init = TRUE;
}
glEnable(GL_POLYGON_STIPPLE);
if(forSel) {
glPolygonStipple(SelMask);
} else {
glPolygonStipple(HoverMask);
}
}
static void StippleTriangle(STriangle *tr, BOOL s, double r, double g, double b)
{
glEnd();
glDisable(GL_LIGHTING);
glColor3d(r, g, b);
Stipple(s);
glBegin(GL_TRIANGLES);
glxVertex3v(tr->a);
glxVertex3v(tr->b);
glxVertex3v(tr->c);
glEnd();
glEnable(GL_LIGHTING);
glDisable(GL_POLYGON_STIPPLE);
glBegin(GL_TRIANGLES);
}
void glxFillMesh(int specColor, SMesh *m, DWORD h, DWORD s1, DWORD s2)
{
glEnable(GL_NORMALIZE);
@ -122,13 +169,7 @@ void glxFillMesh(int specColor, SMesh *m, DWORD h, DWORD s1, DWORD s2)
glNormal3d(n.x, n.y, n.z);
int color;
if((s1 != 0 && tr->meta.face == s1) ||
(s2 != 0 && tr->meta.face == s2))
{
color = RGB(200, 0, 0);
} else if(h != 0 && tr->meta.face == h) {
color = RGB(200, 200, 0);
} else if(specColor < 0) {
if(specColor < 0) {
color = tr->meta.color;
} else {
color = specColor;
@ -146,6 +187,15 @@ void glxFillMesh(int specColor, SMesh *m, DWORD h, DWORD s1, DWORD s2)
glxVertex3v(tr->a);
glxVertex3v(tr->b);
glxVertex3v(tr->c);
if((s1 != 0 && tr->meta.face == s1) ||
(s2 != 0 && tr->meta.face == s2))
{
StippleTriangle(tr, TRUE, 1, 0, 0);
}
if(h != 0 && tr->meta.face == h) {
StippleTriangle(tr, FALSE, 1, 1, 0);
}
}
glEnd();
}

View File

@ -102,12 +102,14 @@ void GraphicsWindow::Init(void) {
projRight.x = 1; projRight.y = projRight.z = 0;
projUp.y = 1; projUp.z = projUp.x = 0;
// And with the latest visible group active
// And with the latest visible group active, or failing that the first
// group after the references
int i;
for(i = 0; i < SS.group.n; i++) {
Group *g = &(SS.group.elem[i]);
if(i == 0 || g->visible) activeGroup = g->h;
if(i == 1 || g->visible) activeGroup = g->h;
}
SS.GetGroup(activeGroup)->Activate();
EnsureValidActives();
@ -248,6 +250,7 @@ void GraphicsWindow::EnsureValidActives(void) {
}
if(i >= SS.group.n) oops();
activeGroup = SS.group.elem[i].h;
SS.GetGroup(activeGroup)->Activate();
change = true;
}
@ -746,7 +749,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
}
// Faces, from the triangle mesh; these are lowest priority
if(s.constraint.v == 0 && s.entity.v == 0 && (showMesh || showShaded)) {
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) {
SMesh *m = &((SS.GetGroup(activeGroup))->mesh);
DWORD v = m->FirstIntersectionWith(mp);
if(v) {
@ -1063,6 +1066,19 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
if(i != MAX_SELECTED) break;
if(hover.entity.v != 0 && SS.GetEntity(hover.entity)->IsFace()) {
// In the interest of speed for the triangle drawing code,
// only two faces may be selected at a time.
int c = 0;
for(i = 0; i < MAX_SELECTED; i++) {
hEntity he = selection[i].entity;
if(he.v != 0 && SS.GetEntity(he)->IsFace()) {
c++;
if(c >= 2) selection[i].Clear();
}
}
}
for(i = 0; i < MAX_SELECTED; i++) {
if(selection[i].IsEmpty()) {
selection[i] = hover;
@ -1147,6 +1163,10 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) {
bool *vb = (bool *)v;
*vb = !*vb;
// The faces are shown as special stippling on the shaded triangle mesh,
// so not meaningful to show them and hide the shaded.
if(!SS.GW.showShaded) SS.GW.showFaces = false;
SS.GW.GeneratePerSolving();
InvalidateGraphics();
SS.TW.Show();

View File

@ -141,6 +141,7 @@ void Group::MenuGroup(int id) {
if(g.type == DRAWING_WORKPLANE) {
SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
}
SS.GetGroup(g.h)->Activate();
SS.GW.AnimateOntoWorkplane();
TextWindow::ScreenSelectGroup(0, g.h.v);
SS.TW.Show();
@ -156,6 +157,15 @@ char *Group::DescriptionString(void) {
return ret;
}
void Group::Activate(void) {
if(type == EXTRUDE || type == IMPORTED) {
SS.GW.showFaces = true;
} else {
SS.GW.showFaces = false;
}
SS.TW.Show();
}
void Group::Generate(IdList<Entity,hEntity> *entity,
IdList<Param,hParam> *param)
{

View File

@ -137,6 +137,7 @@ public:
NameStr name;
void Activate(void);
char *DescriptionString(void);
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);

View File

@ -221,6 +221,10 @@ void TextWindow::Show(void) {
InvalidateText();
}
void TextWindow::ScreenUnselectAll(int link, DWORD v) {
GraphicsWindow::MenuEdit(GraphicsWindow::MNU_UNSELECT_ALL);
}
void TextWindow::DescribeSelection(void) {
Entity *e;
Vector p;
@ -310,6 +314,12 @@ void TextWindow::DescribeSelection(void) {
Printf(false, " radius = %Fi%s", SS.GW.ToString(r));
break;
}
case Entity::FACE_NORMAL_PT:
case Entity::FACE_XPROD:
case Entity::FACE_N_ROT_TRANS:
Printf(false, "%FtPLANE FACE%E");
break;
default:
Printf(true, "%Ft?? ENTITY%E");
break;
@ -335,6 +345,8 @@ void TextWindow::DescribeSelection(void) {
} else {
Printf(true, "%FtSELECTED:%E %d item%s", gs.n, gs.n == 1 ? "" : "s");
}
Printf(true, "%Fl%f%Ll(unselect all)%E", &TextWindow::ScreenUnselectAll);
}
void TextWindow::OneScreenForwardTo(int screen) {
@ -397,9 +409,11 @@ hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints), &(SS.GW.ToggleBool)
);
Printf(false, "%Bt%Ft "
"%Fp%Ll%D%fshaded%E "
"%Fp%Ll%D%ffaces%E "
"%Fp%Ll%D%fmesh%E "
"%Fp%Ll%D%fhidden-lines%E",
hs(SS.GW.showShaded), (DWORD)(&SS.GW.showShaded), &(SS.GW.ToggleBool),
hs(SS.GW.showFaces), (DWORD)(&SS.GW.showFaces), &(SS.GW.ToggleBool),
hs(SS.GW.showMesh), (DWORD)(&SS.GW.showMesh), &(SS.GW.ToggleBool),
hs(SS.GW.showHdnLines), (DWORD)(&SS.GW.showHdnLines), &(SS.GW.ToggleBool)
);
@ -437,6 +451,7 @@ void TextWindow::ScreenActivateGroup(int link, DWORD v) {
Group *g = SS.GetGroup(hg);
g->visible = true;
SS.GW.activeGroup.v = v;
SS.GetGroup(SS.GW.activeGroup)->Activate();
SS.GW.ClearSuper();
}
void TextWindow::ReportHowGroupSolved(hGroup hg) {

7
ui.h
View File

@ -99,12 +99,14 @@ public:
static void ScreenChangeMeshCombine(int link, DWORD v);
static void ScreenColor(int link, DWORD v);
static void ScreenUnselectAll(int link, DWORD v);
static void ScreenNavigation(int link, DWORD v);
// These ones do stuff with the edit control
static void ScreenChangeExprA(int link, DWORD v);
static void ScreenChangeGroupName(int link, DWORD v);
static void ScreenNavigation(int link, DWORD v);
void EditControlDone(char *s);
};
@ -297,6 +299,7 @@ public:
bool showConstraints;
bool showTextWindow;
bool showShaded;
bool showFaces;
bool showMesh;
bool showHdnLines;
static void ToggleBool(int link, DWORD v);