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:
parent
1f70494ce9
commit
a084b32064
64
glhelper.cpp
64
glhelper.cpp
|
@ -111,6 +111,53 @@ void glxColor4d(double r, double g, double b, double a)
|
||||||
if(!ColorLocked) glColor4d(r, g, b, 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)
|
void glxFillMesh(int specColor, SMesh *m, DWORD h, DWORD s1, DWORD s2)
|
||||||
{
|
{
|
||||||
glEnable(GL_NORMALIZE);
|
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);
|
glNormal3d(n.x, n.y, n.z);
|
||||||
|
|
||||||
int color;
|
int color;
|
||||||
if((s1 != 0 && tr->meta.face == s1) ||
|
if(specColor < 0) {
|
||||||
(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) {
|
|
||||||
color = tr->meta.color;
|
color = tr->meta.color;
|
||||||
} else {
|
} else {
|
||||||
color = specColor;
|
color = specColor;
|
||||||
|
@ -146,6 +187,15 @@ void glxFillMesh(int specColor, SMesh *m, DWORD h, DWORD s1, DWORD s2)
|
||||||
glxVertex3v(tr->a);
|
glxVertex3v(tr->a);
|
||||||
glxVertex3v(tr->b);
|
glxVertex3v(tr->b);
|
||||||
glxVertex3v(tr->c);
|
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();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,12 +102,14 @@ void GraphicsWindow::Init(void) {
|
||||||
projRight.x = 1; projRight.y = projRight.z = 0;
|
projRight.x = 1; projRight.y = projRight.z = 0;
|
||||||
projUp.y = 1; projUp.z = projUp.x = 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;
|
int i;
|
||||||
for(i = 0; i < SS.group.n; i++) {
|
for(i = 0; i < SS.group.n; i++) {
|
||||||
Group *g = &(SS.group.elem[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();
|
EnsureValidActives();
|
||||||
|
|
||||||
|
@ -248,6 +250,7 @@ void GraphicsWindow::EnsureValidActives(void) {
|
||||||
}
|
}
|
||||||
if(i >= SS.group.n) oops();
|
if(i >= SS.group.n) oops();
|
||||||
activeGroup = SS.group.elem[i].h;
|
activeGroup = SS.group.elem[i].h;
|
||||||
|
SS.GetGroup(activeGroup)->Activate();
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,7 +749,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faces, from the triangle mesh; these are lowest priority
|
// 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);
|
SMesh *m = &((SS.GetGroup(activeGroup))->mesh);
|
||||||
DWORD v = m->FirstIntersectionWith(mp);
|
DWORD v = m->FirstIntersectionWith(mp);
|
||||||
if(v) {
|
if(v) {
|
||||||
|
@ -1063,6 +1066,19 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
}
|
}
|
||||||
if(i != MAX_SELECTED) break;
|
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++) {
|
for(i = 0; i < MAX_SELECTED; i++) {
|
||||||
if(selection[i].IsEmpty()) {
|
if(selection[i].IsEmpty()) {
|
||||||
selection[i] = hover;
|
selection[i] = hover;
|
||||||
|
@ -1147,6 +1163,10 @@ void GraphicsWindow::ToggleBool(int link, DWORD v) {
|
||||||
bool *vb = (bool *)v;
|
bool *vb = (bool *)v;
|
||||||
*vb = !*vb;
|
*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();
|
SS.GW.GeneratePerSolving();
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
|
|
10
sketch.cpp
10
sketch.cpp
|
@ -141,6 +141,7 @@ void Group::MenuGroup(int id) {
|
||||||
if(g.type == DRAWING_WORKPLANE) {
|
if(g.type == DRAWING_WORKPLANE) {
|
||||||
SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
|
SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
|
||||||
}
|
}
|
||||||
|
SS.GetGroup(g.h)->Activate();
|
||||||
SS.GW.AnimateOntoWorkplane();
|
SS.GW.AnimateOntoWorkplane();
|
||||||
TextWindow::ScreenSelectGroup(0, g.h.v);
|
TextWindow::ScreenSelectGroup(0, g.h.v);
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
|
@ -156,6 +157,15 @@ char *Group::DescriptionString(void) {
|
||||||
return ret;
|
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,
|
void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
IdList<Param,hParam> *param)
|
IdList<Param,hParam> *param)
|
||||||
{
|
{
|
||||||
|
|
1
sketch.h
1
sketch.h
|
@ -137,6 +137,7 @@ public:
|
||||||
NameStr name;
|
NameStr name;
|
||||||
|
|
||||||
|
|
||||||
|
void Activate(void);
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
|
|
||||||
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
||||||
|
|
15
textwin.cpp
15
textwin.cpp
|
@ -221,6 +221,10 @@ void TextWindow::Show(void) {
|
||||||
InvalidateText();
|
InvalidateText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextWindow::ScreenUnselectAll(int link, DWORD v) {
|
||||||
|
GraphicsWindow::MenuEdit(GraphicsWindow::MNU_UNSELECT_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
void TextWindow::DescribeSelection(void) {
|
void TextWindow::DescribeSelection(void) {
|
||||||
Entity *e;
|
Entity *e;
|
||||||
Vector p;
|
Vector p;
|
||||||
|
@ -310,6 +314,12 @@ void TextWindow::DescribeSelection(void) {
|
||||||
Printf(false, " radius = %Fi%s", SS.GW.ToString(r));
|
Printf(false, " radius = %Fi%s", SS.GW.ToString(r));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Entity::FACE_NORMAL_PT:
|
||||||
|
case Entity::FACE_XPROD:
|
||||||
|
case Entity::FACE_N_ROT_TRANS:
|
||||||
|
Printf(false, "%FtPLANE FACE%E");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Printf(true, "%Ft?? ENTITY%E");
|
Printf(true, "%Ft?? ENTITY%E");
|
||||||
break;
|
break;
|
||||||
|
@ -335,6 +345,8 @@ void TextWindow::DescribeSelection(void) {
|
||||||
} else {
|
} else {
|
||||||
Printf(true, "%FtSELECTED:%E %d item%s", gs.n, gs.n == 1 ? "" : "s");
|
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) {
|
void TextWindow::OneScreenForwardTo(int screen) {
|
||||||
|
@ -397,9 +409,11 @@ hs(SS.GW.showConstraints), (DWORD)(&SS.GW.showConstraints), &(SS.GW.ToggleBool)
|
||||||
);
|
);
|
||||||
Printf(false, "%Bt%Ft "
|
Printf(false, "%Bt%Ft "
|
||||||
"%Fp%Ll%D%fshaded%E "
|
"%Fp%Ll%D%fshaded%E "
|
||||||
|
"%Fp%Ll%D%ffaces%E "
|
||||||
"%Fp%Ll%D%fmesh%E "
|
"%Fp%Ll%D%fmesh%E "
|
||||||
"%Fp%Ll%D%fhidden-lines%E",
|
"%Fp%Ll%D%fhidden-lines%E",
|
||||||
hs(SS.GW.showShaded), (DWORD)(&SS.GW.showShaded), &(SS.GW.ToggleBool),
|
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.showMesh), (DWORD)(&SS.GW.showMesh), &(SS.GW.ToggleBool),
|
||||||
hs(SS.GW.showHdnLines), (DWORD)(&SS.GW.showHdnLines), &(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);
|
Group *g = SS.GetGroup(hg);
|
||||||
g->visible = true;
|
g->visible = true;
|
||||||
SS.GW.activeGroup.v = v;
|
SS.GW.activeGroup.v = v;
|
||||||
|
SS.GetGroup(SS.GW.activeGroup)->Activate();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
}
|
}
|
||||||
void TextWindow::ReportHowGroupSolved(hGroup hg) {
|
void TextWindow::ReportHowGroupSolved(hGroup hg) {
|
||||||
|
|
7
ui.h
7
ui.h
|
@ -99,12 +99,14 @@ public:
|
||||||
static void ScreenChangeMeshCombine(int link, DWORD v);
|
static void ScreenChangeMeshCombine(int link, DWORD v);
|
||||||
static void ScreenColor(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
|
// These ones do stuff with the edit control
|
||||||
static void ScreenChangeExprA(int link, DWORD v);
|
static void ScreenChangeExprA(int link, DWORD v);
|
||||||
static void ScreenChangeGroupName(int link, DWORD v);
|
static void ScreenChangeGroupName(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenNavigation(int link, DWORD v);
|
|
||||||
|
|
||||||
void EditControlDone(char *s);
|
void EditControlDone(char *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -297,6 +299,7 @@ public:
|
||||||
bool showConstraints;
|
bool showConstraints;
|
||||||
bool showTextWindow;
|
bool showTextWindow;
|
||||||
bool showShaded;
|
bool showShaded;
|
||||||
|
bool showFaces;
|
||||||
bool showMesh;
|
bool showMesh;
|
||||||
bool showHdnLines;
|
bool showHdnLines;
|
||||||
static void ToggleBool(int link, DWORD v);
|
static void ToggleBool(int link, DWORD v);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user