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:
parent
a74f85e0d1
commit
66c93aab73
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
69
glhelper.cpp
69
glhelper.cpp
@ -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;
|
||||
|
@ -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 {
|
||||
|
2
sketch.h
2
sketch.h
@ -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);
|
||||
|
12
solvespace.h
12
solvespace.h
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user