Add a mechanism to record the lines drawn when we display a

constraint, so that we can export that too. This includes the lines
for the vector font.

A little ugly; it needs some kind of line style (color or width) to
distinguish those lines from the real geometry in the exported
file.

[git-p4: depot-paths = "//depot/solvespace/": change = 2007]
This commit is contained in:
Jonathan Westhues 2009-07-03 12:55:57 -08:00
parent a74f85e0d1
commit 66c93aab73
7 changed files with 102 additions and 84 deletions

View File

@ -19,10 +19,14 @@ bool Constraint::HasLabel(void) {
void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
if(dogd.drawing) {
glBegin(GL_LINE_STRIP);
glxVertex3v(a);
glxVertex3v(b);
glEnd();
if(dogd.sel) {
dogd.sel->AddEdge(a, b);
} else {
glBegin(GL_LINE_STRIP);
glxVertex3v(a);
glxVertex3v(b);
glEnd();
}
} else {
Point2d ap = SS.GW.ProjectPoint(a);
Point2d bp = SS.GW.ProjectPoint(b);
@ -33,6 +37,12 @@ void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
dogd.refp = (a.Plus(b)).ScaledBy(0.5);
}
static void LineCallback(void *fndata, Vector a, Vector b)
{
Constraint *c = (Constraint *)fndata;
c->LineDrawOrGetDistance(a, b);
}
double Constraint::EllipticalInterpolation(double rx, double ry, double theta) {
double ex = rx*cos(theta);
double ey = ry*sin(theta);
@ -70,11 +80,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
}
if(dogd.drawing) {
glPushMatrix();
glxTranslatev(ref);
glxOntoWorkplane(gr, gu);
glxWriteTextRefCenter(s);
glPopMatrix();
glxWriteTextRefCenter(s, ref, gr, gu, LineCallback, this);
} else {
double l = swidth/2 - sheight/2;
l = max(l, 5/SS.GW.scale);
@ -183,12 +189,10 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
// The lines are skew; no wonderful way to illustrate that.
*ref = a0.Plus(b0);
*ref = (*ref).ScaledBy(0.5).Plus(disp.offset);
glPushMatrix();
gu = gu.WithMagnitude(1);
glxTranslatev((*ref).Plus(gu.ScaledBy(-1.5*glxStrHeight())));
glxOntoWorkplane(gr, gu);
glxWriteTextRefCenter("angle between skew lines");
glPopMatrix();
gu = gu.WithMagnitude(1);
Vector trans = (*ref).Plus(gu.ScaledBy(-1.5*glxStrHeight()));
glxWriteTextRefCenter("angle between skew lines",
trans, gr, gu, LineCallback, this);
}
}
@ -500,11 +504,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
if(dogd.drawing) {
glPushMatrix();
glxTranslatev(textAt);
glxOntoWorkplane(u, v);
glxWriteTextRefCenter("T");
glPopMatrix();
glxWriteTextRefCenter("T", textAt, u, v, LineCallback, this);
} else {
dogd.refp = textAt;
Point2d ref = SS.GW.ProjectPoint(dogd.refp);
@ -682,14 +682,12 @@ s:
if(type == AT_MIDPOINT) offset = offset.ScaledBy(-1);
if(dogd.drawing) {
glPushMatrix();
glxTranslatev(m.Plus(offset));
glxOntoWorkplane(r, u);
glxWriteTextRefCenter(
(type == HORIZONTAL) ? "H" : (
(type == VERTICAL) ? "V" : (
(type == AT_MIDPOINT) ? "M" : NULL)));
glPopMatrix();
char *s = (type == HORIZONTAL) ? "H" : (
(type == VERTICAL) ? "V" : (
(type == AT_MIDPOINT) ? "M" : NULL));
glxWriteTextRefCenter(s, m.Plus(offset), r, u,
LineCallback, this);
} else {
dogd.refp = m.Plus(offset);
Point2d ref = SS.GW.ProjectPoint(dogd.refp);
@ -742,12 +740,14 @@ s:
void Constraint::Draw(void) {
dogd.drawing = true;
dogd.sel = NULL;
glLineWidth(1);
DrawOrGetDistance(NULL);
}
double Constraint::GetDistance(Point2d mp) {
dogd.drawing = false;
dogd.sel = NULL;
dogd.mp = mp;
dogd.dmin = 1e12;
@ -758,6 +758,7 @@ double Constraint::GetDistance(Point2d mp) {
Vector Constraint::GetLabelPos(void) {
dogd.drawing = false;
dogd.sel = NULL;
dogd.mp.x = 0; dogd.mp.y = 0;
dogd.dmin = 1e12;
@ -768,6 +769,7 @@ Vector Constraint::GetLabelPos(void) {
Vector Constraint::GetReferencePos(void) {
dogd.drawing = false;
dogd.sel = NULL;
dogd.refp = SS.GW.offset.ScaledBy(-1);
DrawOrGetDistance(NULL);
@ -775,3 +777,10 @@ Vector Constraint::GetReferencePos(void) {
return dogd.refp;
}
void Constraint::GetEdges(SEdgeList *sel) {
dogd.drawing = true;
dogd.sel = sel;
DrawOrGetDistance(NULL);
dogd.sel = NULL;
}

View File

@ -440,11 +440,7 @@ void Entity::DrawOrGetDistance(void) {
char *str = DescriptionString()+5;
if(dogd.drawing) {
glPushMatrix();
glxTranslatev(mm2);
glxOntoWorkplane(u, v);
glxWriteText(str);
glPopMatrix();
glxWriteText(str, mm2, u, v, NULL, NULL);
} else {
Vector pos = mm2.Plus(u.ScaledBy(glxStrWidth(str)/2)).Plus(
v.ScaledBy(glxStrHeight()/2));

View File

@ -135,6 +135,13 @@ void SolveSpace::ExportViewTo(char *filename) {
}
}
if(SS.GW.showConstraints) {
Constraint *c;
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
c->GetEdges(&edges);
}
}
Vector u = SS.GW.projRight,
v = SS.GW.projUp,
n = u.Cross(v),
@ -856,7 +863,7 @@ void PdfFileWriter::Bezier(SBezier *sb) {
//-----------------------------------------------------------------------------
const char *SvgFileWriter::SVG_STYLE =
"stroke-width='1' stroke='black' style='fill: none;'";
"stroke-width='0.1' stroke='black' style='fill: none;'";
void SvgFileWriter::StartFile(void) {
fprintf(f,

View File

@ -22,21 +22,41 @@ double glxStrHeight(void) {
// The characters have height ~21, as they appear in the table.
return 21.0*FONT_SCALE/SS.GW.scale;
}
void glxWriteTextRefCenter(char *str)
void glxWriteTextRefCenter(char *str, Vector t, Vector u, Vector v,
glxLineFn *fn, void *fndata)
{
u = u.WithMagnitude(1);
v = v.WithMagnitude(1);
double scale = FONT_SCALE/SS.GW.scale;
double fh = glxStrHeight();
double fw = glxStrWidth(str);
glPushMatrix();
glTranslated(-fw/2, -fh/2, 0);
// Undo the (+5, +5) offset that glxWriteText applies.
glTranslated(-5*scale, -5*scale, 0);
glxWriteText(str);
glPopMatrix();
t = t.Plus(u.ScaledBy(-fw/2));
t = t.Plus(v.ScaledBy(-fh/2));
// Undo the (+5, +5) offset that glxWriteText applies.
t = t.Plus(u.ScaledBy(-5*scale));
t = t.Plus(v.ScaledBy(-5*scale));
glxWriteText(str, t, u, v, fn, fndata);
}
void glxWriteText(char *str)
static void LineDrawCallback(void *fndata, Vector a, Vector b)
{
glBegin(GL_LINES);
glxVertex3v(a);
glxVertex3v(b);
glEnd();
}
void glxWriteText(char *str, Vector t, Vector u, Vector v,
glxLineFn *fn, void *fndata)
{
if(!fn) fn = LineDrawCallback;
u = u.WithMagnitude(1);
v = v.WithMagnitude(1);
double scale = FONT_SCALE/SS.GW.scale;
int xo = 5;
int yo = 5;
@ -47,20 +67,24 @@ void glxWriteText(char *str)
c -= 32;
glBegin(GL_LINE_STRIP);
int j;
Vector prevp = Vector::From(VERY_POSITIVE, 0, 0);
for(j = 0; j < Font[c].points; j++) {
int x = Font[c].coord[j*2];
int y = Font[c].coord[j*2+1];
if(x == PEN_UP && y == PEN_UP) {
glEnd();
glBegin(GL_LINE_STRIP);
prevp.x = VERY_POSITIVE;
} else {
glVertex3d((xo + x)*scale, (yo + y)*scale, 0);
Vector p = t;
p = p.Plus(u.ScaledBy((xo + x)*scale));
p = p.Plus(v.ScaledBy((yo + y)*scale));
if(prevp.x != VERY_POSITIVE) {
fn(fndata, prevp, p);
}
prevp = p;
}
}
glEnd();
xo += Font[c].width;
}
@ -71,25 +95,6 @@ void glxVertex3v(Vector u)
glVertex3f((GLfloat)u.x, (GLfloat)u.y, (GLfloat)u.z);
}
void glxTranslatev(Vector u)
{
glTranslated((GLdouble)u.x, (GLdouble)u.y, (GLdouble)u.z);
}
void glxOntoWorkplane(Vector u, Vector v)
{
u = u.WithMagnitude(1);
v = v.WithMagnitude(1);
double mat[16];
Vector n = u.Cross(v);
MakeMatrix(mat, u.x, v.x, n.x, 0,
u.y, v.y, n.y, 0,
u.z, v.z, n.z, 0,
0, 0, 0, 1);
glMultMatrixd(mat);
}
void glxLockColorTo(double r, double g, double b)
{
ColorLocked = false;

View File

@ -453,11 +453,9 @@ void Group::Draw(void) {
glEnd();
glLineWidth(1);
glxColor3d(1, 0, 0);
glPushMatrix();
glxTranslatev(polyError.notClosedAt.b);
glxOntoWorkplane(SS.GW.projRight, SS.GW.projUp);
glxWriteText("not closed contour!");
glPopMatrix();
glxWriteText("not closed contour!",
polyError.notClosedAt.b, SS.GW.projRight, SS.GW.projUp,
NULL, NULL);
glEnable(GL_DEPTH_TEST);
}
} else if(polyError.how == POLY_NOT_COPLANAR ||
@ -467,15 +465,12 @@ void Group::Draw(void) {
if(type == DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST);
glxColor3d(1, 0, 0);
glPushMatrix();
glxTranslatev(polyError.errorPointAt);
glxOntoWorkplane(SS.GW.projRight, SS.GW.projUp);
if(polyError.how == POLY_NOT_COPLANAR) {
glxWriteText("points not all coplanar!");
} else {
glxWriteText("contour is self-intersecting!");
}
glPopMatrix();
char *msg = (polyError.how == POLY_NOT_COPLANAR) ?
"points not all coplanar!" :
"contour is self-intersecting!";
glxWriteText(msg,
polyError.errorPointAt, SS.GW.projRight, SS.GW.projUp,
NULL, NULL);
glEnable(GL_DEPTH_TEST);
}
} else {

View File

@ -531,12 +531,14 @@ public:
Point2d mp;
double dmin;
Vector refp;
SEdgeList *sel;
} dogd;
double GetDistance(Point2d mp);
Vector GetLabelPos(void);
Vector GetReferencePos(void);
void Draw(void);
void GetEdges(SEdgeList *sel);
void LineDrawOrGetDistance(Vector a, Vector b);
void DrawOrGetDistance(Vector *labelPos);

View File

@ -184,12 +184,13 @@ void glxDebugPolygon(SPolygon *p);
void glxDrawEdges(SEdgeList *l, bool endpointsToo);
void glxDebugMesh(SMesh *m);
void glxMarkPolygonNormal(SPolygon *p);
void glxWriteText(char *str);
void glxWriteTextRefCenter(char *str);
typedef void glxLineFn(void *data, Vector a, Vector b);
void glxWriteText(char *str, Vector t, Vector u, Vector v,
glxLineFn *fn, void *fndata);
void glxWriteTextRefCenter(char *str, Vector t, Vector u, Vector v,
glxLineFn *fn, void *fndata);
double glxStrWidth(char *str);
double glxStrHeight(void);
void glxTranslatev(Vector u);
void glxOntoWorkplane(Vector u, Vector v);
void glxLockColorTo(double r, double g, double b);
void glxUnlockColor(void);
void glxColor3d(double r, double g, double b);
@ -383,6 +384,9 @@ class VectorFileWriter {
public:
FILE *f;
Vector ptMin, ptMax;
double width;
double r, g, b;
static double MmToPts(double mm);
static bool StringEndsIn(char *str, char *ending);