Trim trailing whitespace.
parent
7c7ac17e4b
commit
c5364fe7a8
|
@ -128,7 +128,7 @@ typedef struct {
|
||||||
Slvs_hEntity entityB;
|
Slvs_hEntity entityB;
|
||||||
Slvs_hEntity entityC;
|
Slvs_hEntity entityC;
|
||||||
Slvs_hEntity entityD;
|
Slvs_hEntity entityD;
|
||||||
|
|
||||||
int other;
|
int other;
|
||||||
int other2;
|
int other2;
|
||||||
} Slvs_Constraint;
|
} Slvs_Constraint;
|
||||||
|
|
|
@ -73,7 +73,7 @@ void SBsp3::InsertInPlane(bool pos2, STriangle *tr, SMesh *m) {
|
||||||
(onFace && !sameNormal && m->keepCoplanar)))
|
(onFace && !sameNormal && m->keepCoplanar)))
|
||||||
{
|
{
|
||||||
m->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
|
m->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
|
||||||
} else if(!(m->flipNormal) && ((pos2 && !onFace) ||
|
} else if(!(m->flipNormal) && ((pos2 && !onFace) ||
|
||||||
(onFace && sameNormal && m->keepCoplanar)))
|
(onFace && sameNormal && m->keepCoplanar)))
|
||||||
{
|
{
|
||||||
m->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
|
m->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
|
||||||
|
@ -180,7 +180,7 @@ SBsp3 *SBsp3::InsertConvex(STriMeta meta, Vector *vertex, int cnt,
|
||||||
}
|
}
|
||||||
onc++;
|
onc++;
|
||||||
} else if(dt > d) {
|
} else if(dt > d) {
|
||||||
isPos[i] = true;
|
isPos[i] = true;
|
||||||
posc++;
|
posc++;
|
||||||
} else {
|
} else {
|
||||||
isNeg[i] = true;
|
isNeg[i] = true;
|
||||||
|
@ -454,7 +454,7 @@ void SBsp3::DebugDraw(void) {
|
||||||
ssglVertex3v(tri.a);
|
ssglVertex3v(tri.a);
|
||||||
ssglVertex3v(tri.b);
|
ssglVertex3v(tri.b);
|
||||||
ssglVertex3v(tri.c);
|
ssglVertex3v(tri.c);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
ssglDepthRangeOffset(0);
|
ssglDepthRangeOffset(0);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
|
@ -172,7 +172,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
|
||||||
MakeSelected(hr.entity(i+1));
|
MakeSelected(hr.entity(i+1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint *c;
|
Constraint *c;
|
||||||
for(c = SS.clipboard.c.First(); c; c = SS.clipboard.c.NextAfter(c)) {
|
for(c = SS.clipboard.c.First(); c; c = SS.clipboard.c.NextAfter(c)) {
|
||||||
if(c->type == Constraint::POINTS_COINCIDENT) {
|
if(c->type == Constraint::POINTS_COINCIDENT) {
|
||||||
|
@ -192,7 +192,7 @@ void GraphicsWindow::MenuClipboard(int id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case MNU_PASTE: {
|
case MNU_PASTE: {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
Vector trans = SS.GW.projRight.ScaledBy(80/SS.GW.scale).Plus(
|
Vector trans = SS.GW.projRight.ScaledBy(80/SS.GW.scale).Plus(
|
||||||
SS.GW.projUp .ScaledBy(40/SS.GW.scale));
|
SS.GW.projUp .ScaledBy(40/SS.GW.scale));
|
||||||
|
@ -206,7 +206,7 @@ void GraphicsWindow::MenuClipboard(int id) {
|
||||||
Error("Clipboard is empty; nothing to paste.");
|
Error("Clipboard is empty; nothing to paste.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane());
|
Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane());
|
||||||
Vector p = SK.GetEntity(wrkpl->point[0])->PointGetNum();
|
Vector p = SK.GetEntity(wrkpl->point[0])->PointGetNum();
|
||||||
SS.TW.shown.paste.times = 1;
|
SS.TW.shown.paste.times = 1;
|
||||||
|
|
|
@ -170,7 +170,7 @@ void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) {
|
||||||
void TextWindow::ShowConfiguration(void) {
|
void TextWindow::ShowConfiguration(void) {
|
||||||
int i;
|
int i;
|
||||||
Printf(true, "%Ft user color (r, g, b)");
|
Printf(true, "%Ft user color (r, g, b)");
|
||||||
|
|
||||||
for(i = 0; i < SS.MODEL_COLORS; i++) {
|
for(i = 0; i < SS.MODEL_COLORS; i++) {
|
||||||
Printf(false, "%Bp #%d: %Bz %Bp (%@, %@, %@) %f%D%Ll%Fl[change]%E",
|
Printf(false, "%Bp #%d: %Bz %Bp (%@, %@, %@) %f%D%Ll%Fl[change]%E",
|
||||||
(i & 1) ? 'd' : 'a',
|
(i & 1) ? 'd' : 'a',
|
||||||
|
@ -181,7 +181,7 @@ void TextWindow::ShowConfiguration(void) {
|
||||||
SS.modelColor[i].blueF(),
|
SS.modelColor[i].blueF(),
|
||||||
&ScreenChangeColor, i);
|
&ScreenChangeColor, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
Printf(false, "%Ft light direction intensity");
|
Printf(false, "%Ft light direction intensity");
|
||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
|
@ -293,7 +293,7 @@ void TextWindow::ShowConfiguration(void) {
|
||||||
Printf(false, " %Fd%f%Ll%c check sketch for closed contour%E",
|
Printf(false, " %Fd%f%Ll%c check sketch for closed contour%E",
|
||||||
&ScreenChangeCheckClosedContour,
|
&ScreenChangeCheckClosedContour,
|
||||||
SS.checkClosedContour ? CHECK_TRUE : CHECK_FALSE);
|
SS.checkClosedContour ? CHECK_TRUE : CHECK_FALSE);
|
||||||
|
|
||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
Printf(false, " %Ftgl vendor %E%s", glGetString(GL_VENDOR));
|
Printf(false, " %Ftgl vendor %E%s", glGetString(GL_VENDOR));
|
||||||
Printf(false, " %Ft renderer %E%s", glGetString(GL_RENDERER));
|
Printf(false, " %Ft renderer %E%s", glGetString(GL_RENDERER));
|
||||||
|
|
|
@ -389,7 +389,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
// the line segment, and choose the longer of these.
|
// the line segment, and choose the longer of these.
|
||||||
ExprVector eap = ea.Minus(ep);
|
ExprVector eap = ea.Minus(ep);
|
||||||
ExprVector ebp = eb.Minus(ep);
|
ExprVector ebp = eb.Minus(ep);
|
||||||
ExprVector elp =
|
ExprVector elp =
|
||||||
(ebp.Magnitude()->Eval() > eap.Magnitude()->Eval()) ?
|
(ebp.Magnitude()->Eval() > eap.Magnitude()->Eval()) ?
|
||||||
ebp : eap;
|
ebp : eap;
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
EntityBase *normal = SK.GetEntity(circle->normal);
|
EntityBase *normal = SK.GetEntity(circle->normal);
|
||||||
ExprVector u = normal->NormalExprsU(),
|
ExprVector u = normal->NormalExprsU(),
|
||||||
v = normal->NormalExprsV();
|
v = normal->NormalExprsV();
|
||||||
|
|
||||||
Expr *du = (center.Minus(pt)).Dot(u),
|
Expr *du = (center.Minus(pt)).Dot(u),
|
||||||
*dv = (center.Minus(pt)).Dot(v);
|
*dv = (center.Minus(pt)).Dot(v);
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
EntityBase *ln = SK.GetEntity(entityA);
|
EntityBase *ln = SK.GetEntity(entityA);
|
||||||
EntityBase *a = SK.GetEntity(ln->point[0]);
|
EntityBase *a = SK.GetEntity(ln->point[0]);
|
||||||
EntityBase *b = SK.GetEntity(ln->point[1]);
|
EntityBase *b = SK.GetEntity(ln->point[1]);
|
||||||
|
|
||||||
Expr *au, *av, *bu, *bv;
|
Expr *au, *av, *bu, *bv;
|
||||||
a->PointGetExprsInWorkplane(workplane, &au, &av);
|
a->PointGetExprsInWorkplane(workplane, &au, &av);
|
||||||
b->PointGetExprsInWorkplane(workplane, &bu, &bv);
|
b->PointGetExprsInWorkplane(workplane, &bu, &bv);
|
||||||
|
@ -601,7 +601,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
ExprVector bu = b->NormalExprsU(),
|
ExprVector bu = b->NormalExprsU(),
|
||||||
bv = b->NormalExprsV(),
|
bv = b->NormalExprsV(),
|
||||||
bn = b->NormalExprsN();
|
bn = b->NormalExprsN();
|
||||||
|
|
||||||
AddEq(l, VectorsParallel(0, an, bn), 0);
|
AddEq(l, VectorsParallel(0, an, bn), 0);
|
||||||
AddEq(l, VectorsParallel(1, an, bn), 1);
|
AddEq(l, VectorsParallel(1, an, bn), 1);
|
||||||
Expr *d1 = au.Dot(bv);
|
Expr *d1 = au.Dot(bv);
|
||||||
|
@ -669,7 +669,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
EntityBase *line = SK.GetEntity(entityB);
|
EntityBase *line = SK.GetEntity(entityB);
|
||||||
|
|
||||||
ExprVector ac = SK.GetEntity(arc->point[0])->PointGetExprs();
|
ExprVector ac = SK.GetEntity(arc->point[0])->PointGetExprs();
|
||||||
ExprVector ap =
|
ExprVector ap =
|
||||||
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs();
|
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs();
|
||||||
|
|
||||||
ExprVector ld = line->VectorGetExprs();
|
ExprVector ld = line->VectorGetExprs();
|
||||||
|
@ -682,7 +682,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
|
||||||
case CUBIC_LINE_TANGENT: {
|
case CUBIC_LINE_TANGENT: {
|
||||||
EntityBase *cubic = SK.GetEntity(entityA);
|
EntityBase *cubic = SK.GetEntity(entityA);
|
||||||
EntityBase *line = SK.GetEntity(entityB);
|
EntityBase *line = SK.GetEntity(entityB);
|
||||||
|
|
||||||
ExprVector a;
|
ExprVector a;
|
||||||
if(other) {
|
if(other) {
|
||||||
a = cubic->CubicGetFinishTangentExprs();
|
a = cubic->CubicGetFinishTangentExprs();
|
||||||
|
|
|
@ -33,7 +33,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
|
||||||
|
|
||||||
Request *r = SK.request.FindByIdNoOops(e->h.request());
|
Request *r = SK.request.FindByIdNoOops(e->h.request());
|
||||||
if(!r) return;
|
if(!r) return;
|
||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
r->font.strcpy(SS.fonts.l.elem[i].FontFileBaseName());
|
r->font.strcpy(SS.fonts.l.elem[i].FontFileBaseName());
|
||||||
SS.MarkGroupDirty(r->group);
|
SS.MarkGroupDirty(r->group);
|
||||||
|
@ -195,7 +195,7 @@ void TextWindow::DescribeSelection(void) {
|
||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
Printf(false, "%FtIN GROUP%E %s", g->DescriptionString());
|
Printf(false, "%FtIN GROUP%E %s", g->DescriptionString());
|
||||||
if(e->workplane.v == Entity::FREE_IN_3D.v) {
|
if(e->workplane.v == Entity::FREE_IN_3D.v) {
|
||||||
Printf(false, "%FtNOT LOCKED IN WORKPLANE%E");
|
Printf(false, "%FtNOT LOCKED IN WORKPLANE%E");
|
||||||
} else {
|
} else {
|
||||||
Entity *w = SK.GetEntity(e->workplane);
|
Entity *w = SK.GetEntity(e->workplane);
|
||||||
Printf(false, "%FtIN WORKPLANE%E %s", w->DescriptionString());
|
Printf(false, "%FtIN WORKPLANE%E %s", w->DescriptionString());
|
||||||
|
@ -263,7 +263,7 @@ void TextWindow::DescribeSelection(void) {
|
||||||
double theta = acos(v0.Dot(v1));
|
double theta = acos(v0.Dot(v1));
|
||||||
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
|
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
|
||||||
while(theta < PI/2) theta += PI;
|
while(theta < PI/2) theta += PI;
|
||||||
while(theta > PI/2) theta -= PI;
|
while(theta > PI/2) theta -= PI;
|
||||||
Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI);
|
Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI);
|
||||||
} else if(gs.n == 2 && gs.faces == 2) {
|
} else if(gs.n == 2 && gs.faces == 2) {
|
||||||
Printf(false, "%FtTWO PLANE FACES");
|
Printf(false, "%FtTWO PLANE FACES");
|
||||||
|
@ -281,7 +281,7 @@ void TextWindow::DescribeSelection(void) {
|
||||||
double theta = acos(n0.Dot(n1));
|
double theta = acos(n0.Dot(n1));
|
||||||
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
|
Printf(true, " angle = %Fi%2%E degrees", theta*180/PI);
|
||||||
while(theta < PI/2) theta += PI;
|
while(theta < PI/2) theta += PI;
|
||||||
while(theta > PI/2) theta -= PI;
|
while(theta > PI/2) theta -= PI;
|
||||||
Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI);
|
Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI);
|
||||||
|
|
||||||
if(fabs(theta) < 0.01) {
|
if(fabs(theta) < 0.01) {
|
||||||
|
@ -298,7 +298,7 @@ void TextWindow::DescribeSelection(void) {
|
||||||
Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s");
|
Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shown.screen == SCREEN_STYLE_INFO &&
|
if(shown.screen == SCREEN_STYLE_INFO &&
|
||||||
shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0)
|
shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0)
|
||||||
{
|
{
|
||||||
// If we are showing a screen for a particular style, then offer the
|
// If we are showing a screen for a particular style, then offer the
|
||||||
|
|
28
src/draw.cpp
28
src/draw.cpp
|
@ -465,7 +465,7 @@ void GraphicsWindow::Paint(void) {
|
||||||
width = w; height = h;
|
width = w; height = h;
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glScaled(scale*2.0/w, scale*2.0/h, scale*1.0/30000);
|
glScaled(scale*2.0/w, scale*2.0/h, scale*1.0/30000);
|
||||||
|
@ -492,7 +492,7 @@ void GraphicsWindow::Paint(void) {
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
glMultMatrixd(mat);
|
glMultMatrixd(mat);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
|
@ -504,10 +504,10 @@ void GraphicsWindow::Paint(void) {
|
||||||
// drawn with leaks in the mesh
|
// drawn with leaks in the mesh
|
||||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
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.
|
// At the same depth, we want later lines drawn over earlier.
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
|
||||||
|
@ -522,9 +522,9 @@ void GraphicsWindow::Paint(void) {
|
||||||
// And show the text window, which has info to debug it
|
// And show the text window, which has info to debug it
|
||||||
ForceTextWindowShown();
|
ForceTextWindowShown();
|
||||||
}
|
}
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glClearDepth(1.0);
|
glClearDepth(1.0);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
if(SS.bgImage.fromFile) {
|
if(SS.bgImage.fromFile) {
|
||||||
// If a background image is loaded, then we draw it now as a texture.
|
// If a background image is loaded, then we draw it now as a texture.
|
||||||
|
@ -631,7 +631,7 @@ void GraphicsWindow::Paint(void) {
|
||||||
|
|
||||||
double g = SS.gridSpacing;
|
double g = SS.gridSpacing;
|
||||||
|
|
||||||
double umin = VERY_POSITIVE, umax = VERY_NEGATIVE,
|
double umin = VERY_POSITIVE, umax = VERY_NEGATIVE,
|
||||||
vmin = VERY_POSITIVE, vmax = VERY_NEGATIVE;
|
vmin = VERY_POSITIVE, vmax = VERY_NEGATIVE;
|
||||||
int a;
|
int a;
|
||||||
for(a = 0; a < 4; a++) {
|
for(a = 0; a < 4; a++) {
|
||||||
|
@ -642,7 +642,7 @@ void GraphicsWindow::Paint(void) {
|
||||||
if(a == 2 || a == 3) horiz = horiz.ScaledBy(-1);
|
if(a == 2 || a == 3) horiz = horiz.ScaledBy(-1);
|
||||||
if(a == 1 || a == 3) vert = vert. ScaledBy(-1);
|
if(a == 1 || a == 3) vert = vert. ScaledBy(-1);
|
||||||
Vector tp = horiz.Plus(vert).Minus(offset);
|
Vector tp = horiz.Plus(vert).Minus(offset);
|
||||||
|
|
||||||
// Project the point into our grid plane, normal to the screen
|
// Project the point into our grid plane, normal to the screen
|
||||||
// (not to the grid plane). If the plane is on edge then this is
|
// (not to the grid plane). If the plane is on edge then this is
|
||||||
// impossible so don't try to draw the grid.
|
// impossible so don't try to draw the grid.
|
||||||
|
@ -684,11 +684,11 @@ void GraphicsWindow::Paint(void) {
|
||||||
ssglVertex3v(wp.Plus(wu.ScaledBy(i0*g)).Plus(wv.ScaledBy(j*g)));
|
ssglVertex3v(wp.Plus(wu.ScaledBy(i0*g)).Plus(wv.ScaledBy(j*g)));
|
||||||
ssglVertex3v(wp.Plus(wu.ScaledBy(i1*g)).Plus(wv.ScaledBy(j*g)));
|
ssglVertex3v(wp.Plus(wu.ScaledBy(i1*g)).Plus(wv.ScaledBy(j*g)));
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
// Clear the depth buffer, so that the grid is at the very back of
|
// Clear the depth buffer, so that the grid is at the very back of
|
||||||
// the Z order.
|
// the Z order.
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
nogrid:;
|
nogrid:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,7 +732,7 @@ nogrid:;
|
||||||
ssglDrawEdges(&(SS.nakedEdges), true);
|
ssglDrawEdges(&(SS.nakedEdges), true);
|
||||||
|
|
||||||
// Then redraw whatever the mouse is hovering over, highlighted.
|
// Then redraw whatever the mouse is hovering over, highlighted.
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
ssglLockColorTo(Style::Color(Style::HOVERED));
|
ssglLockColorTo(Style::Color(Style::HOVERED));
|
||||||
hover.Draw();
|
hover.Draw();
|
||||||
|
|
||||||
|
@ -803,12 +803,12 @@ nogrid:;
|
||||||
|
|
||||||
ssglWriteText("(x, y) = (0, 0) for file just exported",
|
ssglWriteText("(x, y) = (0, 0) for file just exported",
|
||||||
DEFAULT_TEXT_HEIGHT,
|
DEFAULT_TEXT_HEIGHT,
|
||||||
p.Plus(u.ScaledBy(10/scale)).Plus(v.ScaledBy(10/scale)),
|
p.Plus(u.ScaledBy(10/scale)).Plus(v.ScaledBy(10/scale)),
|
||||||
u, v, NULL, NULL);
|
u, v, NULL, NULL);
|
||||||
ssglWriteText("press Esc to clear this message",
|
ssglWriteText("press Esc to clear this message",
|
||||||
DEFAULT_TEXT_HEIGHT,
|
DEFAULT_TEXT_HEIGHT,
|
||||||
p.Plus(u.ScaledBy(40/scale)).Plus(
|
p.Plus(u.ScaledBy(40/scale)).Plus(
|
||||||
v.ScaledBy(-(DEFAULT_TEXT_HEIGHT)/scale)),
|
v.ScaledBy(-(DEFAULT_TEXT_HEIGHT)/scale)),
|
||||||
u, v, NULL, NULL);
|
u, v, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,7 @@ void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn) {
|
||||||
Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
|
Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
|
||||||
Vector ab = a.Minus(b);
|
Vector ab = a.Minus(b);
|
||||||
Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);
|
Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);
|
||||||
|
|
||||||
LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
|
LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skew;
|
bool skew;
|
||||||
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da),
|
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da),
|
||||||
b0, b0.Plus(db), &skew);
|
b0, b0.Plus(db), &skew);
|
||||||
|
|
||||||
if(!skew) {
|
if(!skew) {
|
||||||
|
@ -670,9 +670,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
|
|
||||||
if(other) da = da.ScaledBy(-1);
|
if(other) da = da.ScaledBy(-1);
|
||||||
|
|
||||||
DoArcForAngle(a0, da, b0, db,
|
DoArcForAngle(a0, da, b0, db,
|
||||||
da.WithMagnitude(40/SS.GW.scale), &ref);
|
da.WithMagnitude(40/SS.GW.scale), &ref);
|
||||||
DoArcForAngle(c0, dc, d0, dd,
|
DoArcForAngle(c0, dc, d0, dd,
|
||||||
dc.WithMagnitude(40/SS.GW.scale), &ref);
|
dc.WithMagnitude(40/SS.GW.scale), &ref);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -681,7 +681,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
case ANGLE: {
|
case ANGLE: {
|
||||||
Entity *a = SK.GetEntity(entityA);
|
Entity *a = SK.GetEntity(entityA);
|
||||||
Entity *b = SK.GetEntity(entityB);
|
Entity *b = SK.GetEntity(entityB);
|
||||||
|
|
||||||
Vector a0 = a->VectorGetRefPoint();
|
Vector a0 = a->VectorGetRefPoint();
|
||||||
Vector b0 = b->VectorGetRefPoint();
|
Vector b0 = b->VectorGetRefPoint();
|
||||||
Vector da = a->VectorGetNum();
|
Vector da = a->VectorGetNum();
|
||||||
|
@ -742,7 +742,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
Entity *arc = SK.GetEntity(entityA);
|
Entity *arc = SK.GetEntity(entityA);
|
||||||
Entity *norm = SK.GetEntity(arc->normal);
|
Entity *norm = SK.GetEntity(arc->normal);
|
||||||
Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
|
Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
|
||||||
Vector p =
|
Vector p =
|
||||||
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
|
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
|
||||||
Vector r = p.Minus(c);
|
Vector r = p.Minus(c);
|
||||||
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
|
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
|
||||||
|
@ -763,7 +763,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
|
|
||||||
Entity *cubic = SK.GetEntity(entityA);
|
Entity *cubic = SK.GetEntity(entityA);
|
||||||
Vector p = other ? cubic->CubicGetFinishNum() :
|
Vector p = other ? cubic->CubicGetFinishNum() :
|
||||||
cubic->CubicGetStartNum();
|
cubic->CubicGetStartNum();
|
||||||
Vector dir = SK.GetEntity(entityB)->VectorGetNum();
|
Vector dir = SK.GetEntity(entityB)->VectorGetNum();
|
||||||
Vector out = n.Cross(dir);
|
Vector out = n.Cross(dir);
|
||||||
textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
|
textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
|
||||||
|
@ -1067,7 +1067,7 @@ double Constraint::GetDistance(Point2d mp) {
|
||||||
dogd.dmin = 1e12;
|
dogd.dmin = 1e12;
|
||||||
|
|
||||||
DrawOrGetDistance(NULL);
|
DrawOrGetDistance(NULL);
|
||||||
|
|
||||||
return dogd.dmin;
|
return dogd.dmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat) {
|
||||||
} else {
|
} else {
|
||||||
ssglFatLine(a, b, dogd.lineWidth/SS.GW.scale);
|
ssglFatLine(a, b, dogd.lineWidth/SS.GW.scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssglDepthRangeOffset(0);
|
ssglDepthRangeOffset(0);
|
||||||
} else {
|
} else {
|
||||||
Point2d ap = SS.GW.ProjectPoint(a);
|
Point2d ap = SS.GW.ProjectPoint(a);
|
||||||
|
@ -150,7 +150,7 @@ double Entity::GetDistance(Point2d mp) {
|
||||||
dogd.dmin = 1e12;
|
dogd.dmin = 1e12;
|
||||||
|
|
||||||
DrawOrGetDistance();
|
DrawOrGetDistance();
|
||||||
|
|
||||||
return dogd.dmin;
|
return dogd.dmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ void Entity::ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) {
|
||||||
int pts = periodic ? 4 + ep : 2 + ep;
|
int pts = periodic ? 4 + ep : 2 + ep;
|
||||||
|
|
||||||
int i, j, a;
|
int i, j, a;
|
||||||
|
|
||||||
// The starting and finishing control points that define our end tangents
|
// The starting and finishing control points that define our end tangents
|
||||||
// (if the spline isn't periodic), and the on-curve points.
|
// (if the spline isn't periodic), and the on-curve points.
|
||||||
Vector ctrl_s = Vector::From(0, 0, 0);
|
Vector ctrl_s = Vector::From(0, 0, 0);
|
||||||
|
@ -269,7 +269,7 @@ void Entity::ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) {
|
||||||
BandedMatrix bm;
|
BandedMatrix bm;
|
||||||
ZERO(&bm);
|
ZERO(&bm);
|
||||||
bm.n = n;
|
bm.n = n;
|
||||||
|
|
||||||
for(i = 0; i < n; i++) {
|
for(i = 0; i < n; i++) {
|
||||||
int im, it, ip;
|
int im, it, ip;
|
||||||
if(periodic) {
|
if(periodic) {
|
||||||
|
@ -318,7 +318,7 @@ void Entity::ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) {
|
||||||
} else {
|
} else {
|
||||||
// The wrapping would work, except when n = 1 and everything
|
// The wrapping would work, except when n = 1 and everything
|
||||||
// wraps to zero...
|
// wraps to zero...
|
||||||
if(i > 0) bm.A[i][i - 1] = eq.x;
|
if(i > 0) bm.A[i][i - 1] = eq.x;
|
||||||
bm.A[i][i] = eq.y;
|
bm.A[i][i] = eq.y;
|
||||||
if(i < (n-1)) bm.A[i][i + 1] = eq.z;
|
if(i < (n-1)) bm.A[i][i + 1] = eq.z;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TTF_TEXT: {
|
case TTF_TEXT: {
|
||||||
Vector topLeft = SK.GetEntity(point[0])->PointGetNum();
|
Vector topLeft = SK.GetEntity(point[0])->PointGetNum();
|
||||||
Vector botLeft = SK.GetEntity(point[1])->PointGetNum();
|
Vector botLeft = SK.GetEntity(point[1])->PointGetNum();
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
Quaternion ScaledBy(double s);
|
Quaternion ScaledBy(double s);
|
||||||
double Magnitude(void);
|
double Magnitude(void);
|
||||||
Quaternion WithMagnitude(double s);
|
Quaternion WithMagnitude(double s);
|
||||||
|
|
||||||
// Call a rotation matrix [ u' v' n' ]'; this returns the first and
|
// Call a rotation matrix [ u' v' n' ]'; this returns the first and
|
||||||
// second rows, where that matrix is generated by this quaternion
|
// second rows, where that matrix is generated by this quaternion
|
||||||
Vector RotationU(void);
|
Vector RotationU(void);
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
class Vector {
|
class Vector {
|
||||||
public:
|
public:
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
|
|
||||||
static Vector From(double x, double y, double z);
|
static Vector From(double x, double y, double z);
|
||||||
static Vector From(hParam x, hParam y, hParam z);
|
static Vector From(hParam x, hParam y, hParam z);
|
||||||
static Vector AtIntersectionOfPlanes(Vector n1, double d1,
|
static Vector AtIntersectionOfPlanes(Vector n1, double d1,
|
||||||
|
@ -102,7 +102,7 @@ public:
|
||||||
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
||||||
Vector p0, Vector p1, bool segment);
|
Vector p0, Vector p1, bool segment);
|
||||||
bool OutsideAndNotOn(Vector maxv, Vector minv);
|
bool OutsideAndNotOn(Vector maxv, Vector minv);
|
||||||
Vector InPerspective(Vector u, Vector v, Vector n,
|
Vector InPerspective(Vector u, Vector v, Vector n,
|
||||||
Vector origin, double cameraTan);
|
Vector origin, double cameraTan);
|
||||||
Point2d Project2d(Vector u, Vector v);
|
Point2d Project2d(Vector u, Vector v);
|
||||||
Point2d ProjectXy(void);
|
Point2d ProjectXy(void);
|
||||||
|
@ -112,7 +112,7 @@ public:
|
||||||
class Vector4 {
|
class Vector4 {
|
||||||
public:
|
public:
|
||||||
double w, x, y, z;
|
double w, x, y, z;
|
||||||
|
|
||||||
static Vector4 From(double w, double x, double y, double z);
|
static Vector4 From(double w, double x, double y, double z);
|
||||||
static Vector4 From(double w, Vector v3);
|
static Vector4 From(double w, Vector v3);
|
||||||
static Vector4 Blend(Vector4 a, Vector4 b, double t);
|
static Vector4 Blend(Vector4 a, Vector4 b, double t);
|
||||||
|
|
|
@ -280,7 +280,7 @@ void EntityBase::NormalForceTo(Quaternion q) {
|
||||||
break;
|
break;
|
||||||
case NORMAL_N_ROT: {
|
case NORMAL_N_ROT: {
|
||||||
Quaternion qp = q.Times(numNormal.Inverse());
|
Quaternion qp = q.Times(numNormal.Inverse());
|
||||||
|
|
||||||
SK.GetParam(param[0])->val = qp.w;
|
SK.GetParam(param[0])->val = qp.w;
|
||||||
SK.GetParam(param[1])->val = qp.vx;
|
SK.GetParam(param[1])->val = qp.vx;
|
||||||
SK.GetParam(param[2])->val = qp.vy;
|
SK.GetParam(param[2])->val = qp.vy;
|
||||||
|
@ -756,8 +756,8 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) {
|
||||||
ConstraintBase *c = &(SK.constraint.elem[i]);
|
ConstraintBase *c = &(SK.constraint.elem[i]);
|
||||||
if(c->group.v != group.v) continue;
|
if(c->group.v != group.v) continue;
|
||||||
if(c->type != Constraint::POINTS_COINCIDENT) continue;
|
if(c->type != Constraint::POINTS_COINCIDENT) continue;
|
||||||
|
|
||||||
if((c->ptA.v == point[1].v && c->ptB.v == point[2].v) ||
|
if((c->ptA.v == point[1].v && c->ptB.v == point[2].v) ||
|
||||||
(c->ptA.v == point[2].v && c->ptB.v == point[1].v))
|
(c->ptA.v == point[2].v && c->ptB.v == point[1].v))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,7 +20,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
|
||||||
"or use Export 2d View to export bare lines and curves.");
|
"or use Export 2d View to export bare lines and curves.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The plane in which the exported section lies; need this because we'll
|
// The plane in which the exported section lies; need this because we'll
|
||||||
// reorient from that plane into the xy plane before exporting.
|
// reorient from that plane into the xy plane before exporting.
|
||||||
Vector origin, u, v, n;
|
Vector origin, u, v, n;
|
||||||
|
@ -81,7 +81,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
|
||||||
|
|
||||||
// If there's a shell, then grab the edges and possibly Beziers.
|
// If there's a shell, then grab the edges and possibly Beziers.
|
||||||
g->runningShell.MakeSectionEdgesInto(n, d,
|
g->runningShell.MakeSectionEdgesInto(n, d,
|
||||||
&el,
|
&el,
|
||||||
(SS.exportPwlCurves || fabs(SS.exportOffset) > LENGTH_EPS) ? NULL : &bl);
|
(SS.exportPwlCurves || fabs(SS.exportOffset) > LENGTH_EPS) ? NULL : &bl);
|
||||||
|
|
||||||
// All of these are solid model edges, so use the appropriate style.
|
// All of these are solid model edges, so use the appropriate style.
|
||||||
|
@ -559,7 +559,7 @@ void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) {
|
||||||
closeEnough = false;
|
closeEnough = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(closeEnough || depth > 3) {
|
if(closeEnough || depth > 3) {
|
||||||
Bezier(&bnr);
|
Bezier(&bnr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -681,7 +681,7 @@ void SolveSpace::ExportAsPngTo(char *filename) {
|
||||||
SS.showToolbar = false;
|
SS.showToolbar = false;
|
||||||
SS.GW.Paint();
|
SS.GW.Paint();
|
||||||
SS.showToolbar = prevShowToolbar;
|
SS.showToolbar = prevShowToolbar;
|
||||||
|
|
||||||
FILE *f = fopen(filename, "wb");
|
FILE *f = fopen(filename, "wb");
|
||||||
if(!f) goto err;
|
if(!f) goto err;
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ void SolveSpace::ExportAsPngTo(char *filename) {
|
||||||
png_set_IHDR(png_ptr, info_ptr, w, h,
|
png_set_IHDR(png_ptr, info_ptr, w, h,
|
||||||
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||||
PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
|
||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
// Get the pixel data from the framebuffer
|
// Get the pixel data from the framebuffer
|
||||||
|
@ -724,7 +724,7 @@ void SolveSpace::ExportAsPngTo(char *filename) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
Error("Error writing PNG file '%s'", filename);
|
Error("Error writing PNG file '%s'", filename);
|
||||||
if(f) fclose(f);
|
if(f) fclose(f);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -168,7 +168,7 @@ int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
|
||||||
fprintf(f, "));\n");
|
fprintf(f, "));\n");
|
||||||
|
|
||||||
int fb = id + 1;
|
int fb = id + 1;
|
||||||
fprintf(f, "#%d=%s('',#%d,.T.);\n",
|
fprintf(f, "#%d=%s('',#%d,.T.);\n",
|
||||||
fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id);
|
fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id);
|
||||||
|
|
||||||
id += 2;
|
id += 2;
|
||||||
|
@ -218,7 +218,7 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) {
|
||||||
// The control points for the untrimmed surface.
|
// The control points for the untrimmed surface.
|
||||||
for(i = 0; i <= ss->degm; i++) {
|
for(i = 0; i <= ss->degm; i++) {
|
||||||
for(j = 0; j <= ss->degn; j++) {
|
for(j = 0; j <= ss->degn; j++) {
|
||||||
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
||||||
srfid + 1 + j + i*(ss->degn + 1),
|
srfid + 1 + j + i*(ss->degn + 1),
|
||||||
CO(ss->ctrl[i][j]));
|
CO(ss->ctrl[i][j]));
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) {
|
||||||
int fob = ExportCurveLoop(loop, false);
|
int fob = ExportCurveLoop(loop, false);
|
||||||
listOfLoops.Add(&fob);
|
listOfLoops.Add(&fob);
|
||||||
|
|
||||||
// And create the face inner boundaries from any inner loops that
|
// And create the face inner boundaries from any inner loops that
|
||||||
// lie within this contour.
|
// lie within this contour.
|
||||||
loop = sbls->l.NextAfter(loop);
|
loop = sbls->l.NextAfter(loop);
|
||||||
for(; loop; loop = sbls->l.NextAfter(loop)) {
|
for(; loop; loop = sbls->l.NextAfter(loop)) {
|
||||||
|
@ -302,7 +302,7 @@ void StepFileWriter::ExportSurfacesTo(char *file) {
|
||||||
|
|
||||||
if(shell->surface.n == 0) {
|
if(shell->surface.n == 0) {
|
||||||
Error("The model does not contain any surfaces to export.%s",
|
Error("The model does not contain any surfaces to export.%s",
|
||||||
g->runningMesh.l.n > 0 ?
|
g->runningMesh.l.n > 0 ?
|
||||||
"\n\nThe model does contain triangles from a mesh, but "
|
"\n\nThe model does contain triangles from a mesh, but "
|
||||||
"a triangle mesh cannot be exported as a STEP file. Try "
|
"a triangle mesh cannot be exported as a STEP file. Try "
|
||||||
"File -> Export Mesh... instead." : "");
|
"File -> Export Mesh... instead." : "");
|
||||||
|
|
|
@ -272,7 +272,7 @@ void EpsFileWriter::FinishAndCloseFile(void) {
|
||||||
// a correct xref table.
|
// a correct xref table.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void PdfFileWriter::StartFile(void) {
|
void PdfFileWriter::StartFile(void) {
|
||||||
if((ptMax.x - ptMin.x) > 200*25.4 ||
|
if((ptMax.x - ptMin.x) > 200*25.4 ||
|
||||||
(ptMax.y - ptMin.y) > 200*25.4)
|
(ptMax.y - ptMin.y) > 200*25.4)
|
||||||
{
|
{
|
||||||
Message("PDF page size exceeds 200 by 200 inches; many viewers may "
|
Message("PDF page size exceeds 200 by 200 inches; many viewers may "
|
||||||
|
@ -283,7 +283,7 @@ void PdfFileWriter::StartFile(void) {
|
||||||
"%%PDF-1.1\r\n"
|
"%%PDF-1.1\r\n"
|
||||||
"%%%c%c%c%c\r\n",
|
"%%%c%c%c%c\r\n",
|
||||||
0xe2, 0xe3, 0xcf, 0xd3);
|
0xe2, 0xe3, 0xcf, 0xd3);
|
||||||
|
|
||||||
xref[1] = (uint32_t)ftell(f);
|
xref[1] = (uint32_t)ftell(f);
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"1 0 obj\r\n"
|
"1 0 obj\r\n"
|
||||||
|
@ -369,13 +369,13 @@ void PdfFileWriter::FinishAndCloseFile(void) {
|
||||||
"9 0 obj\r\n"
|
"9 0 obj\r\n"
|
||||||
" << /Creator (SolveSpace)\r\n"
|
" << /Creator (SolveSpace)\r\n"
|
||||||
" >>\r\n");
|
" >>\r\n");
|
||||||
|
|
||||||
uint32_t xrefStart = (uint32_t)ftell(f);
|
uint32_t xrefStart = (uint32_t)ftell(f);
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"xref\r\n"
|
"xref\r\n"
|
||||||
"0 10\r\n"
|
"0 10\r\n"
|
||||||
"0000000000 65535 f\r\n");
|
"0000000000 65535 f\r\n");
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i <= 9; i++) {
|
for(i = 1; i <= 9; i++) {
|
||||||
fprintf(f, "%010d %05d n\r\n", xref[i], 0);
|
fprintf(f, "%010d %05d n\r\n", xref[i], 0);
|
||||||
|
@ -673,7 +673,7 @@ void GCodeFileWriter::FinishAndCloseFile(void) {
|
||||||
SS.MmToString(SS.gCode.feed));
|
SS.MmToString(SS.gCode.feed));
|
||||||
}
|
}
|
||||||
// Move up to a clearance plane 5mm above the work.
|
// Move up to a clearance plane 5mm above the work.
|
||||||
fprintf(f, "G00 Z%s\r\n",
|
fprintf(f, "G00 Z%s\r\n",
|
||||||
SS.MmToString(SS.gCode.depth < 0 ? +5 : -5));
|
SS.MmToString(SS.gCode.depth < 0 ? +5 : -5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,7 +346,7 @@ Expr *Expr::PartialWrt(hParam p) {
|
||||||
db = b->PartialWrt(p);
|
db = b->PartialWrt(p);
|
||||||
return (a->Times(db))->Plus(b->Times(da));
|
return (a->Times(db))->Plus(b->Times(da));
|
||||||
|
|
||||||
case DIV:
|
case DIV:
|
||||||
da = a->PartialWrt(p);
|
da = a->PartialWrt(p);
|
||||||
db = b->PartialWrt(p);
|
db = b->PartialWrt(p);
|
||||||
return ((da->Times(b))->Minus(a->Times(db)))->Div(b->Square());
|
return ((da->Times(b))->Minus(a->Times(db)))->Div(b->Square());
|
||||||
|
@ -673,7 +673,7 @@ void Expr::Parse(void) {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
Expr *n = Next();
|
Expr *n = Next();
|
||||||
if(!n) throw "end of expression unexpected";
|
if(!n) throw "end of expression unexpected";
|
||||||
|
|
||||||
if(n->op == CONSTANT) {
|
if(n->op == CONSTANT) {
|
||||||
PushOperand(n);
|
PushOperand(n);
|
||||||
Consume();
|
Consume();
|
||||||
|
|
16
src/file.cpp
16
src/file.cpp
|
@ -240,7 +240,7 @@ void SolveSpace::SaveUsingTable(int type) {
|
||||||
fprintf(fh, "{\n");
|
fprintf(fh, "{\n");
|
||||||
for(j = 0; j < p->M.n; j++) {
|
for(j = 0; j < p->M.n; j++) {
|
||||||
EntityMap *em = &(p->M.elem[j]);
|
EntityMap *em = &(p->M.elem[j]);
|
||||||
fprintf(fh, " %d %08x %d\n",
|
fprintf(fh, " %d %08x %d\n",
|
||||||
em->h.v, em->input.v, em->copyNumber);
|
em->h.v, em->input.v, em->copyNumber);
|
||||||
}
|
}
|
||||||
fprintf(fh, "}");
|
fprintf(fh, "}");
|
||||||
|
@ -262,7 +262,7 @@ bool SolveSpace::SaveToFile(char *filename) {
|
||||||
SS.GenerateAll(0, INT_MAX);
|
SS.GenerateAll(0, INT_MAX);
|
||||||
|
|
||||||
fh = fopen(filename, "wb");
|
fh = fopen(filename, "wb");
|
||||||
if(!fh) {
|
if(!fh) {
|
||||||
Error("Couldn't write to file '%s'", filename);
|
Error("Couldn't write to file '%s'", filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ bool SolveSpace::SaveToFile(char *filename) {
|
||||||
i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]);
|
i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STrimBy *stb;
|
STrimBy *stb;
|
||||||
for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) {
|
for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) {
|
||||||
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
||||||
|
@ -428,7 +428,7 @@ bool SolveSpace::LoadFromFile(char *filename) {
|
||||||
fileLoadError = false;
|
fileLoadError = false;
|
||||||
|
|
||||||
fh = fopen(filename, "rb");
|
fh = fopen(filename, "rb");
|
||||||
if(!fh) {
|
if(!fh) {
|
||||||
Error("Couldn't read from file '%s'", filename);
|
Error("Couldn't read from file '%s'", filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +448,7 @@ bool SolveSpace::LoadFromFile(char *filename) {
|
||||||
if(s) *s = '\0';
|
if(s) *s = '\0';
|
||||||
|
|
||||||
if(*line == '\0') continue;
|
if(*line == '\0') continue;
|
||||||
|
|
||||||
char *e = strchr(line, '=');
|
char *e = strchr(line, '=');
|
||||||
if(e) {
|
if(e) {
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
|
@ -530,7 +530,7 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le,
|
||||||
if(s) *s = '\0';
|
if(s) *s = '\0';
|
||||||
|
|
||||||
if(*line == '\0') continue;
|
if(*line == '\0') continue;
|
||||||
|
|
||||||
char *e = strchr(line, '=');
|
char *e = strchr(line, '=');
|
||||||
if(e) {
|
if(e) {
|
||||||
*e = '\0';
|
*e = '\0';
|
||||||
|
@ -559,8 +559,8 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le,
|
||||||
if(sscanf(line, "Triangle %x %x "
|
if(sscanf(line, "Triangle %x %x "
|
||||||
"%lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
"%lf %lf %lf %lf %lf %lf %lf %lf %lf",
|
||||||
&(tr.meta.face), &rgb,
|
&(tr.meta.face), &rgb,
|
||||||
&(tr.a.x), &(tr.a.y), &(tr.a.z),
|
&(tr.a.x), &(tr.a.y), &(tr.a.z),
|
||||||
&(tr.b.x), &(tr.b.y), &(tr.b.z),
|
&(tr.b.x), &(tr.b.y), &(tr.b.z),
|
||||||
&(tr.c.x), &(tr.c.y), &(tr.c.z)) != 11)
|
&(tr.c.x), &(tr.c.y), &(tr.c.z)) != 11)
|
||||||
{
|
{
|
||||||
oops();
|
oops();
|
||||||
|
|
|
@ -338,7 +338,7 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
|
||||||
}
|
}
|
||||||
memset(&deleted, 0, sizeof(deleted));
|
memset(&deleted, 0, sizeof(deleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeAllTemporary();
|
FreeAllTemporary();
|
||||||
allConsistent = true;
|
allConsistent = true;
|
||||||
return;
|
return;
|
||||||
|
@ -372,7 +372,7 @@ void SolveSpace::ForceReferences(void) {
|
||||||
SK.GetParam(origin->param[1])->known = true;
|
SK.GetParam(origin->param[1])->known = true;
|
||||||
SK.GetParam(origin->param[2])->known = true;
|
SK.GetParam(origin->param[2])->known = true;
|
||||||
// The quaternion that defines the rotation, from the table.
|
// The quaternion that defines the rotation, from the table.
|
||||||
Entity *normal = SK.GetEntity(wrkpl->normal);
|
Entity *normal = SK.GetEntity(wrkpl->normal);
|
||||||
normal->NormalForceTo(Quat[i].q);
|
normal->NormalForceTo(Quat[i].q);
|
||||||
SK.GetParam(normal->param[0])->known = true;
|
SK.GetParam(normal->param[0])->known = true;
|
||||||
SK.GetParam(normal->param[1])->known = true;
|
SK.GetParam(normal->param[1])->known = true;
|
||||||
|
|
|
@ -89,7 +89,7 @@ void ssglWriteText(const char *str, double h, Vector t, Vector u, Vector v,
|
||||||
double scale = FONT_SCALE(h)/SS.GW.scale;
|
double scale = FONT_SCALE(h)/SS.GW.scale;
|
||||||
int xo = 5;
|
int xo = 5;
|
||||||
int yo = 5;
|
int yo = 5;
|
||||||
|
|
||||||
for(; *str; str++) {
|
for(; *str; str++) {
|
||||||
int c = *str;
|
int c = *str;
|
||||||
if(c < 32 || c > 126) c = 32;
|
if(c < 32 || c > 126) c = 32;
|
||||||
|
@ -311,7 +311,7 @@ void ssglFillMesh(RgbColor specColor, SMesh *m, uint32_t h, uint32_t s1, uint32_
|
||||||
ssglVertex3v(tr->c);
|
ssglVertex3v(tr->c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((s1 != 0 && tr->meta.face == s1) ||
|
if((s1 != 0 && tr->meta.face == s1) ||
|
||||||
(s2 != 0 && tr->meta.face == s2))
|
(s2 != 0 && tr->meta.face == s2))
|
||||||
{
|
{
|
||||||
StippleTriangle(tr, true, rgbSelected);
|
StippleTriangle(tr, true, rgbSelected);
|
||||||
|
|
|
@ -364,7 +364,7 @@ void GraphicsWindow::ZoomToFit(bool includingInvisibles) {
|
||||||
|
|
||||||
offset = offset.Plus(projRight.ScaledBy(-xm)).Plus(
|
offset = offset.Plus(projRight.ScaledBy(-xm)).Plus(
|
||||||
projUp. ScaledBy(-ym));
|
projUp. ScaledBy(-ym));
|
||||||
|
|
||||||
// And based on this, we calculate the scale and offset
|
// And based on this, we calculate the scale and offset
|
||||||
if(EXACT(dx == 0 && dy == 0)) {
|
if(EXACT(dx == 0 && dy == 0)) {
|
||||||
scale = 5;
|
scale = 5;
|
||||||
|
@ -692,7 +692,7 @@ Vector GraphicsWindow::SnapToGrid(Vector p) {
|
||||||
pp.x = floor((pp.x / SS.gridSpacing) + 0.5)*SS.gridSpacing;
|
pp.x = floor((pp.x / SS.gridSpacing) + 0.5)*SS.gridSpacing;
|
||||||
pp.y = floor((pp.y / SS.gridSpacing) + 0.5)*SS.gridSpacing;
|
pp.y = floor((pp.y / SS.gridSpacing) + 0.5)*SS.gridSpacing;
|
||||||
pp.z = 0;
|
pp.z = 0;
|
||||||
|
|
||||||
return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo);
|
return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,7 +756,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
|
|
||||||
Vector st = e->EndpointStart(),
|
Vector st = e->EndpointStart(),
|
||||||
fi = e->EndpointFinish();
|
fi = e->EndpointFinish();
|
||||||
|
|
||||||
bool onChain = false, alreadySelected = false;
|
bool onChain = false, alreadySelected = false;
|
||||||
List<Selection> *ls = &(SS.GW.selection);
|
List<Selection> *ls = &(SS.GW.selection);
|
||||||
for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) {
|
for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) {
|
||||||
|
@ -874,7 +874,7 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||||
case MNU_UNDO:
|
case MNU_UNDO:
|
||||||
SS.UndoUndo();
|
SS.UndoUndo();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MNU_REDO:
|
case MNU_REDO:
|
||||||
SS.UndoRedo();
|
SS.UndoRedo();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -260,7 +260,7 @@ void Group::TransformImportedBy(Vector t, Quaternion q) {
|
||||||
|
|
||||||
Quaternion qg = Quaternion::From(qw, qx, qy, qz);
|
Quaternion qg = Quaternion::From(qw, qx, qy, qz);
|
||||||
qg = q.Times(qg);
|
qg = q.Times(qg);
|
||||||
|
|
||||||
Vector tg = Vector::From(tx, ty, tz);
|
Vector tg = Vector::From(tx, ty, tz);
|
||||||
tg = tg.Plus(t);
|
tg = tg.Plus(t);
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(4), 0);
|
AddParam(param, h.param(4), 0);
|
||||||
AddParam(param, h.param(5), 0);
|
AddParam(param, h.param(5), 0);
|
||||||
AddParam(param, h.param(6), 0);
|
AddParam(param, h.param(6), 0);
|
||||||
|
|
||||||
for(i = 0; i < impEntity.n; i++) {
|
for(i = 0; i < impEntity.n; i++) {
|
||||||
Entity *ie = &(impEntity.elem[i]);
|
Entity *ie = &(impEntity.elem[i]);
|
||||||
CopyEntity(entity, ie, 0, 0,
|
CopyEntity(entity, ie, 0, 0,
|
||||||
|
@ -753,7 +753,7 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
|
||||||
|
|
||||||
// If the entity came from an imported file where it was invisible then
|
// If the entity came from an imported file where it was invisible then
|
||||||
// ep->actiVisble will be false, and we should hide it. Or if the entity
|
// ep->actiVisble will be false, and we should hide it. Or if the entity
|
||||||
// came from a copy (e.g. step and repeat) of a force-hidden imported
|
// came from a copy (e.g. step and repeat) of a force-hidden imported
|
||||||
// entity, then we also want to hide it.
|
// entity, then we also want to hide it.
|
||||||
en.forceHidden = (!ep->actVisible) || ep->forceHidden;
|
en.forceHidden = (!ep->actVisible) || ep->forceHidden;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ void Group::GenerateLoops(void) {
|
||||||
bezierLoops.Clear();
|
bezierLoops.Clear();
|
||||||
bezierOpens.Clear();
|
bezierOpens.Clear();
|
||||||
|
|
||||||
if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
|
if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
|
||||||
type == ROTATE || type == TRANSLATE || type == IMPORTED)
|
type == ROTATE || type == TRANSLATE || type == IMPORTED)
|
||||||
{
|
{
|
||||||
bool allClosed = false, allCoplanar = false, allNonZeroLen = false;
|
bool allClosed = false, allCoplanar = false, allNonZeroLen = false;
|
||||||
|
@ -179,7 +179,7 @@ void Group::GenerateForBoolean(T *prevs, T *thiss, T *outs, int how) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::GenerateShellAndMesh(void) {
|
void Group::GenerateShellAndMesh(void) {
|
||||||
bool prevBooleanFailed = booleanFailed;
|
bool prevBooleanFailed = booleanFailed;
|
||||||
booleanFailed = false;
|
booleanFailed = false;
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ void Group::GenerateShellAndMesh(void) {
|
||||||
} else {
|
} else {
|
||||||
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
|
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SBezierLoopSetSet *sblss = &(src->bezierLoops);
|
SBezierLoopSetSet *sblss = &(src->bezierLoops);
|
||||||
SBezierLoopSet *sbls;
|
SBezierLoopSet *sbls;
|
||||||
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
|
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
|
||||||
|
|
|
@ -90,7 +90,7 @@ void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
|
||||||
Slvs_Param *sp = &(ssys->param[i]);
|
Slvs_Param *sp = &(ssys->param[i]);
|
||||||
Param p;
|
Param p;
|
||||||
ZERO(&p);
|
ZERO(&p);
|
||||||
|
|
||||||
p.h.v = sp->h;
|
p.h.v = sp->h;
|
||||||
p.val = sp->val;
|
p.val = sp->val;
|
||||||
SK.param.Add(&p);
|
SK.param.Add(&p);
|
||||||
|
|
32
src/mesh.cpp
32
src/mesh.cpp
|
@ -83,7 +83,7 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
|
||||||
// Select the naked edges in our resulting open mesh.
|
// Select the naked edges in our resulting open mesh.
|
||||||
SKdNode *root = SKdNode::From(&m);
|
SKdNode *root = SKdNode::From(&m);
|
||||||
root->SnapToMesh(&m);
|
root->SnapToMesh(&m);
|
||||||
root->MakeCertainEdgesInto(sel, SKdNode::NAKED_OR_SELF_INTER_EDGES,
|
root->MakeCertainEdgesInto(sel, SKdNode::NAKED_OR_SELF_INTER_EDGES,
|
||||||
false, NULL, NULL);
|
false, NULL, NULL);
|
||||||
|
|
||||||
m.Clear();
|
m.Clear();
|
||||||
|
@ -91,7 +91,7 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
|
||||||
|
|
||||||
void SMesh::MakeEmphasizedEdgesInto(SEdgeList *sel) {
|
void SMesh::MakeEmphasizedEdgesInto(SEdgeList *sel) {
|
||||||
SKdNode *root = SKdNode::From(this);
|
SKdNode *root = SKdNode::From(this);
|
||||||
root->MakeCertainEdgesInto(sel, SKdNode::EMPHASIZED_EDGES,
|
root->MakeCertainEdgesInto(sel, SKdNode::EMPHASIZED_EDGES,
|
||||||
false, NULL, NULL);
|
false, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void SMesh::Simplify(int start) {
|
||||||
|
|
||||||
for(j = 0; j < convc; j++) {
|
for(j = 0; j < convc; j++) {
|
||||||
Vector a = conv[WRAP((j-1), convc)],
|
Vector a = conv[WRAP((j-1), convc)],
|
||||||
b = conv[j],
|
b = conv[j],
|
||||||
d = conv[WRAP((j+1), convc)],
|
d = conv[WRAP((j+1), convc)],
|
||||||
e = conv[WRAP((j+2), convc)];
|
e = conv[WRAP((j+2), convc)];
|
||||||
|
|
||||||
|
@ -182,11 +182,11 @@ void SMesh::Simplify(int start) {
|
||||||
|
|
||||||
bDot /= min(ab.Magnitude(), bc.Magnitude());
|
bDot /= min(ab.Magnitude(), bc.Magnitude());
|
||||||
dDot /= min(cd.Magnitude(), de.Magnitude());
|
dDot /= min(cd.Magnitude(), de.Magnitude());
|
||||||
|
|
||||||
if(fabs(bDot) < LENGTH_EPS && fabs(dDot) < LENGTH_EPS) {
|
if(fabs(bDot) < LENGTH_EPS && fabs(dDot) < LENGTH_EPS) {
|
||||||
conv[WRAP((j+1), convc)] = c;
|
conv[WRAP((j+1), convc)] = c;
|
||||||
// and remove the vertex at j, which is a dup
|
// and remove the vertex at j, which is a dup
|
||||||
memmove(conv+j, conv+j+1,
|
memmove(conv+j, conv+j+1,
|
||||||
(convc - j - 1)*sizeof(conv[0]));
|
(convc - j - 1)*sizeof(conv[0]));
|
||||||
convc--;
|
convc--;
|
||||||
} else if(fabs(bDot) < LENGTH_EPS && dDot > 0) {
|
} else if(fabs(bDot) < LENGTH_EPS && dDot > 0) {
|
||||||
|
@ -214,7 +214,7 @@ void SMesh::Simplify(int start) {
|
||||||
// still generates a convex polygon
|
// still generates a convex polygon
|
||||||
for(i = 0; i < convc; i++) {
|
for(i = 0; i < convc; i++) {
|
||||||
Vector a = conv[WRAP((i-1), convc)],
|
Vector a = conv[WRAP((i-1), convc)],
|
||||||
b = conv[i],
|
b = conv[i],
|
||||||
c = conv[WRAP((i+1), convc)];
|
c = conv[WRAP((i+1), convc)];
|
||||||
Vector ab = b.Minus(a);
|
Vector ab = b.Minus(a);
|
||||||
Vector bc = c.Minus(b);
|
Vector bc = c.Minus(b);
|
||||||
|
@ -354,9 +354,9 @@ uint32_t SMesh::FirstIntersectionWith(Point2d mp) {
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
STriangleLl *STriangleLl::Alloc(void)
|
STriangleLl *STriangleLl::Alloc(void)
|
||||||
{ return (STriangleLl *)AllocTemporary(sizeof(STriangleLl)); }
|
{ return (STriangleLl *)AllocTemporary(sizeof(STriangleLl)); }
|
||||||
SKdNode *SKdNode::Alloc(void)
|
SKdNode *SKdNode::Alloc(void)
|
||||||
{ return (SKdNode *)AllocTemporary(sizeof(SKdNode)); }
|
{ return (SKdNode *)AllocTemporary(sizeof(SKdNode)); }
|
||||||
|
|
||||||
SKdNode *SKdNode::From(SMesh *m) {
|
SKdNode *SKdNode::From(SMesh *m) {
|
||||||
|
@ -413,11 +413,11 @@ SKdNode *SKdNode::From(STriangleLl *tll) {
|
||||||
|
|
||||||
for(ll = tll; ll; ll = ll->next) {
|
for(ll = tll; ll; ll = ll->next) {
|
||||||
STriangle *tr = ll->tri;
|
STriangle *tr = ll->tri;
|
||||||
|
|
||||||
double a = (tr->a).Element(i),
|
double a = (tr->a).Element(i),
|
||||||
b = (tr->b).Element(i),
|
b = (tr->b).Element(i),
|
||||||
c = (tr->c).Element(i);
|
c = (tr->c).Element(i);
|
||||||
|
|
||||||
if(a < split[i] + KDTREE_EPS ||
|
if(a < split[i] + KDTREE_EPS ||
|
||||||
b < split[i] + KDTREE_EPS ||
|
b < split[i] + KDTREE_EPS ||
|
||||||
c < split[i] + KDTREE_EPS)
|
c < split[i] + KDTREE_EPS)
|
||||||
|
@ -450,11 +450,11 @@ SKdNode *SKdNode::From(STriangleLl *tll) {
|
||||||
STriangleLl *lgt, *llt; lgt = llt = NULL;
|
STriangleLl *lgt, *llt; lgt = llt = NULL;
|
||||||
for(ll = tll; ll; ll = ll->next) {
|
for(ll = tll; ll; ll = ll->next) {
|
||||||
STriangle *tr = ll->tri;
|
STriangle *tr = ll->tri;
|
||||||
|
|
||||||
double a = (tr->a).Element(which),
|
double a = (tr->a).Element(which),
|
||||||
b = (tr->b).Element(which),
|
b = (tr->b).Element(which),
|
||||||
c = (tr->c).Element(which);
|
c = (tr->c).Element(which);
|
||||||
|
|
||||||
if(a < split[which] + KDTREE_EPS ||
|
if(a < split[which] + KDTREE_EPS ||
|
||||||
b < split[which] + KDTREE_EPS ||
|
b < split[which] + KDTREE_EPS ||
|
||||||
c < split[which] + KDTREE_EPS)
|
c < split[which] + KDTREE_EPS)
|
||||||
|
@ -618,7 +618,7 @@ void SKdNode::SnapToMesh(SMesh *m) {
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l.elem[i]);
|
||||||
for(j = 0; j < 3; j++) {
|
for(j = 0; j < 3; j++) {
|
||||||
Vector v = ((j == 0) ? tr->a :
|
Vector v = ((j == 0) ? tr->a :
|
||||||
((j == 1) ? tr->b :
|
((j == 1) ? tr->b :
|
||||||
tr->c));
|
tr->c));
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) {
|
||||||
}
|
}
|
||||||
seln.Clear();
|
seln.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
|
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
|
||||||
if(se->auxB) {
|
if(se->auxB) {
|
||||||
// Lies above or on the triangle plane, so triangle doesn't
|
// Lies above or on the triangle plane, so triangle doesn't
|
||||||
|
@ -812,7 +812,7 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are a leaf node; so we iterate over all the triangles in our
|
// We are a leaf node; so we iterate over all the triangles in our
|
||||||
// linked list.
|
// linked list.
|
||||||
STriangleLl *ll;
|
STriangleLl *ll;
|
||||||
|
@ -820,7 +820,7 @@ void SKdNode::FindEdgeOn(Vector a, Vector b, int *n, int cnt,
|
||||||
STriangle *tr = ll->tri;
|
STriangle *tr = ll->tri;
|
||||||
|
|
||||||
if(tr->tag == cnt) continue;
|
if(tr->tag == cnt) continue;
|
||||||
|
|
||||||
// Test if this triangle matches up with the given edge
|
// Test if this triangle matches up with the given edge
|
||||||
if((a.Equals(tr->b) && b.Equals(tr->a)) ||
|
if((a.Equals(tr->b) && b.Equals(tr->a)) ||
|
||||||
(a.Equals(tr->c) && b.Equals(tr->b)) ||
|
(a.Equals(tr->c) && b.Equals(tr->b)) ||
|
||||||
|
|
|
@ -200,7 +200,7 @@ void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) {
|
||||||
if(!e->IsPoint()) continue;
|
if(!e->IsPoint()) continue;
|
||||||
if(e->group.v != pt->group.v) continue;
|
if(e->group.v != pt->group.v) continue;
|
||||||
if(e->workplane.v != pt->workplane.v) continue;
|
if(e->workplane.v != pt->workplane.v) continue;
|
||||||
|
|
||||||
ev = e->PointGetNum();
|
ev = e->PointGetNum();
|
||||||
if(!ev.Equals(ptv)) continue;
|
if(!ev.Equals(ptv)) continue;
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ void GraphicsWindow::MakeTangentArc(void) {
|
||||||
Entity *e = SK.GetEntity(r->h.entity(0));
|
Entity *e = SK.GetEntity(r->h.entity(0));
|
||||||
Vector ps = e->EndpointStart(),
|
Vector ps = e->EndpointStart(),
|
||||||
pf = e->EndpointFinish();
|
pf = e->EndpointFinish();
|
||||||
|
|
||||||
if(ps.Equals(pshared) || pf.Equals(pshared)) {
|
if(ps.Equals(pshared) || pf.Equals(pshared)) {
|
||||||
if(c < 2) {
|
if(c < 2) {
|
||||||
// We record the entity and request and their handles,
|
// We record the entity and request and their handles,
|
||||||
|
@ -315,7 +315,7 @@ void GraphicsWindow::MakeTangentArc(void) {
|
||||||
r = SS.tangentArcRadius;
|
r = SS.tangentArcRadius;
|
||||||
} else {
|
} else {
|
||||||
r = 200/scale;
|
r = 200/scale;
|
||||||
// Set the radius so that no more than one third of the
|
// Set the radius so that no more than one third of the
|
||||||
// line segment disappears.
|
// line segment disappears.
|
||||||
r = min(r, pc[0].LengthForAuto()*tan(theta/2));
|
r = min(r, pc[0].LengthForAuto()*tan(theta/2));
|
||||||
r = min(r, pc[1].LengthForAuto()*tan(theta/2));;
|
r = min(r, pc[1].LengthForAuto()*tan(theta/2));;
|
||||||
|
@ -378,7 +378,7 @@ void GraphicsWindow::MakeTangentArc(void) {
|
||||||
SK.GetEntity(earc->point[0])->PointForceTo(center);
|
SK.GetEntity(earc->point[0])->PointForceTo(center);
|
||||||
SK.GetEntity(earc->point[a])->PointForceTo(pc[0].PointAt(t[0]));
|
SK.GetEntity(earc->point[a])->PointForceTo(pc[0].PointAt(t[0]));
|
||||||
SK.GetEntity(earc->point[b])->PointForceTo(pc[1].PointAt(t[1]));
|
SK.GetEntity(earc->point[b])->PointForceTo(pc[1].PointAt(t[1]));
|
||||||
|
|
||||||
earc = NULL;
|
earc = NULL;
|
||||||
|
|
||||||
pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
|
pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
|
||||||
|
@ -569,7 +569,7 @@ hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
|
||||||
Request *r = &(SK.request.elem[i]);
|
Request *r = &(SK.request.elem[i]);
|
||||||
if(r->group.v != activeGroup.v) continue;
|
if(r->group.v != activeGroup.v) continue;
|
||||||
if(r->type != reqType) continue;
|
if(r->type != reqType) continue;
|
||||||
|
|
||||||
// If the user wants to keep the old entities around, they can just
|
// If the user wants to keep the old entities around, they can just
|
||||||
// mark them construction first.
|
// mark them construction first.
|
||||||
if(he.v == r->h.entity(0).v && !r->construction) {
|
if(he.v == r->h.entity(0).v && !r->construction) {
|
||||||
|
@ -590,7 +590,7 @@ void GraphicsWindow::SplitLinesOrCurves(void) {
|
||||||
|
|
||||||
GroupSelection();
|
GroupSelection();
|
||||||
if(!(gs.n == 2 &&(gs.lineSegments +
|
if(!(gs.n == 2 &&(gs.lineSegments +
|
||||||
gs.circlesOrArcs +
|
gs.circlesOrArcs +
|
||||||
gs.cubics +
|
gs.cubics +
|
||||||
gs.periodicCubics) == 2))
|
gs.periodicCubics) == 2))
|
||||||
{
|
{
|
||||||
|
@ -603,7 +603,7 @@ void GraphicsWindow::SplitLinesOrCurves(void) {
|
||||||
hb = gs.entity[1];
|
hb = gs.entity[1];
|
||||||
Entity *ea = SK.GetEntity(ha),
|
Entity *ea = SK.GetEntity(ha),
|
||||||
*eb = SK.GetEntity(hb);
|
*eb = SK.GetEntity(hb);
|
||||||
|
|
||||||
// Compute the possibly-rational Bezier curves for each of these entities
|
// Compute the possibly-rational Bezier curves for each of these entities
|
||||||
SBezierList sbla, sblb;
|
SBezierList sbla, sblb;
|
||||||
ZERO(&sbla);
|
ZERO(&sbla);
|
||||||
|
|
|
@ -46,7 +46,7 @@ void GraphicsWindow::StartDraggingByEntity(hEntity he) {
|
||||||
Entity *e = SK.GetEntity(he);
|
Entity *e = SK.GetEntity(he);
|
||||||
if(e->IsPoint()) {
|
if(e->IsPoint()) {
|
||||||
AddPointToDraggedList(e->h);
|
AddPointToDraggedList(e->h);
|
||||||
} else if(e->type == Entity::LINE_SEGMENT ||
|
} else if(e->type == Entity::LINE_SEGMENT ||
|
||||||
e->type == Entity::ARC_OF_CIRCLE ||
|
e->type == Entity::ARC_OF_CIRCLE ||
|
||||||
e->type == Entity::CUBIC ||
|
e->type == Entity::CUBIC ||
|
||||||
e->type == Entity::CUBIC_PERIODIC ||
|
e->type == Entity::CUBIC_PERIODIC ||
|
||||||
|
@ -54,7 +54,7 @@ void GraphicsWindow::StartDraggingByEntity(hEntity he) {
|
||||||
e->type == Entity::TTF_TEXT)
|
e->type == Entity::TTF_TEXT)
|
||||||
{
|
{
|
||||||
int pts;
|
int pts;
|
||||||
EntReqTable::GetEntityInfo(e->type, e->extraPoints,
|
EntReqTable::GetEntityInfo(e->type, e->extraPoints,
|
||||||
NULL, &pts, NULL, NULL);
|
NULL, &pts, NULL, NULL);
|
||||||
for(int i = 0; i < pts; i++) {
|
for(int i = 0; i < pts; i++) {
|
||||||
AddPointToDraggedList(e->point[i]);
|
AddPointToDraggedList(e->point[i]);
|
||||||
|
@ -166,7 +166,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
havePainted = false;
|
havePainted = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pending.operation == 0) {
|
if(pending.operation == 0) {
|
||||||
double dm = orig.mouse.DistanceTo(mp);
|
double dm = orig.mouse.DistanceTo(mp);
|
||||||
// If we're currently not doing anything, then see if we should
|
// If we're currently not doing anything, then see if we should
|
||||||
|
@ -204,7 +204,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
hover.Clear();
|
hover.Clear();
|
||||||
pending.operation = DRAGGING_POINTS;
|
pending.operation = DRAGGING_POINTS;
|
||||||
}
|
}
|
||||||
} else if(hover.constraint.v &&
|
} else if(hover.constraint.v &&
|
||||||
SK.GetConstraint(hover.constraint)->HasLabel())
|
SK.GetConstraint(hover.constraint)->HasLabel())
|
||||||
{
|
{
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
|
@ -749,7 +749,7 @@ bool GraphicsWindow::ConstrainPointByHovered(hEntity pt) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(e->IsCircle()) {
|
if(e->IsCircle()) {
|
||||||
Constraint::Constrain(Constraint::PT_ON_CIRCLE,
|
Constraint::Constrain(Constraint::PT_ON_CIRCLE,
|
||||||
pt, Entity::NO_ENTITY, e->h);
|
pt, Entity::NO_ENTITY, e->h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +832,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
Constraint::Constrain(
|
Constraint::Constrain(
|
||||||
(i % 2) ? Constraint::HORIZONTAL : Constraint::VERTICAL,
|
(i % 2) ? Constraint::HORIZONTAL : Constraint::VERTICAL,
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
||||||
lns[i].entity(0));
|
lns[i].entity(0));
|
||||||
}
|
}
|
||||||
ConstrainPointByHovered(lns[2].entity(1));
|
ConstrainPointByHovered(lns[2].entity(1));
|
||||||
|
@ -907,7 +907,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
}
|
}
|
||||||
hr = AddRequest(Request::WORKPLANE);
|
hr = AddRequest(Request::WORKPLANE);
|
||||||
SK.GetEntity(hr.entity(1))->PointForceTo(v);
|
SK.GetEntity(hr.entity(1))->PointForceTo(v);
|
||||||
SK.GetEntity(hr.entity(32))->NormalForceTo(
|
SK.GetEntity(hr.entity(32))->NormalForceTo(
|
||||||
Quaternion::From(SS.GW.projRight, SS.GW.projUp));
|
Quaternion::From(SS.GW.projRight, SS.GW.projUp));
|
||||||
ConstrainPointByHovered(hr.entity(1));
|
ConstrainPointByHovered(hr.entity(1));
|
||||||
|
|
||||||
|
@ -1091,7 +1091,7 @@ void GraphicsWindow::MouseLeftUp(double mx, double my) {
|
||||||
// be the start of marquee selection. But don't do that on the
|
// be the start of marquee selection. But don't do that on the
|
||||||
// left click to cancel a context menu. The time delay is an ugly
|
// left click to cancel a context menu. The time delay is an ugly
|
||||||
// hack.
|
// hack.
|
||||||
if(hover.IsEmpty() &&
|
if(hover.IsEmpty() &&
|
||||||
(contextMenuCancelTime == 0 ||
|
(contextMenuCancelTime == 0 ||
|
||||||
(GetMilliseconds() - contextMenuCancelTime) > 200))
|
(GetMilliseconds() - contextMenuCancelTime) > 200))
|
||||||
{
|
{
|
||||||
|
@ -1311,7 +1311,7 @@ void GraphicsWindow::SpaceNavigatorMoved(double tx, double ty, double tz,
|
||||||
// projection
|
// projection
|
||||||
offset = offset.Plus(projRight.ScaledBy(tx/scale));
|
offset = offset.Plus(projRight.ScaledBy(tx/scale));
|
||||||
offset = offset.Plus(projUp.ScaledBy(ty/scale));
|
offset = offset.Plus(projUp.ScaledBy(ty/scale));
|
||||||
scale *= exp(0.001*tz);
|
scale *= exp(0.001*tz);
|
||||||
|
|
||||||
if(aam > 0.0) {
|
if(aam > 0.0) {
|
||||||
projRight = projRight.RotatedAbout(aa, -aam);
|
projRight = projRight.RotatedAbout(aa, -aam);
|
||||||
|
|
|
@ -70,7 +70,7 @@ bool SEdge::EdgeCrosses(Vector ea, Vector eb, Vector *ppi, SPointList *spl) {
|
||||||
double t_eps = LENGTH_EPS/d.Magnitude();
|
double t_eps = LENGTH_EPS/d.Magnitude();
|
||||||
|
|
||||||
double dist_a, dist_b;
|
double dist_a, dist_b;
|
||||||
double t, tthis;
|
double t, tthis;
|
||||||
bool skew;
|
bool skew;
|
||||||
Vector pi;
|
Vector pi;
|
||||||
bool inOrEdge0, inOrEdge1;
|
bool inOrEdge0, inOrEdge1;
|
||||||
|
@ -239,7 +239,7 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) {
|
||||||
// but they are considered to cross if they are coincident and overlapping.
|
// but they are considered to cross if they are coincident and overlapping.
|
||||||
// If pi is not NULL, then a crossing is returned in that.
|
// If pi is not NULL, then a crossing is returned in that.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int SEdgeList::AnyEdgeCrossings(Vector a, Vector b,
|
int SEdgeList::AnyEdgeCrossings(Vector a, Vector b,
|
||||||
Vector *ppi, SPointList *spl)
|
Vector *ppi, SPointList *spl)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
@ -367,7 +367,7 @@ SKdNodeEdges *SKdNodeEdges::From(SEdgeLl *sell) {
|
||||||
n->which = 2;
|
n->which = 2;
|
||||||
}
|
}
|
||||||
n->c = ptAve.Element(n->which);
|
n->c = ptAve.Element(n->which);
|
||||||
|
|
||||||
if(totaln < 3 || totaln == gtln[n->which] || totaln == ltln[n->which]) {
|
if(totaln < 3 || totaln == gtln[n->which] || totaln == ltln[n->which]) {
|
||||||
n->edges = sell;
|
n->edges = sell;
|
||||||
// and we're a leaf node
|
// and we're a leaf node
|
||||||
|
@ -438,7 +438,7 @@ static int ByTAlongLine(const void *av, const void *bv)
|
||||||
{
|
{
|
||||||
SEdge *a = (SEdge *)av,
|
SEdge *a = (SEdge *)av,
|
||||||
*b = (SEdge *)bv;
|
*b = (SEdge *)bv;
|
||||||
|
|
||||||
double ta = (a->a.Minus(LineStart)).DivPivoting(LineDirection),
|
double ta = (a->a.Minus(LineStart)).DivPivoting(LineDirection),
|
||||||
tb = (b->a.Minus(LineStart)).DivPivoting(LineDirection);
|
tb = (b->a.Minus(LineStart)).DivPivoting(LineDirection);
|
||||||
|
|
||||||
|
@ -689,7 +689,7 @@ void SPolygon::FixContourDirections(void) {
|
||||||
(sc->timesEnclosed)++;
|
(sc->timesEnclosed)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clockwise = sc->IsClockwiseProjdToNormal(normal);
|
bool clockwise = sc->IsClockwiseProjdToNormal(normal);
|
||||||
if((clockwise && outer) || (!clockwise && !outer)) {
|
if((clockwise && outer) || (!clockwise && !outer)) {
|
||||||
sc->Reverse();
|
sc->Reverse();
|
||||||
|
@ -777,7 +777,7 @@ static bool IntersectionOfLines(double x0A, double y0A, double dxA, double dyA,
|
||||||
if(fabs(A[0][0]*A[1][1] - A[0][1]*A[1][0]) < LENGTH_EPS) {
|
if(fabs(A[0][0]*A[1][1] - A[0][1]*A[1][0]) < LENGTH_EPS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solve
|
// Solve
|
||||||
double v = A[1][0] / A[0][0];
|
double v = A[1][0] / A[0][0];
|
||||||
A[1][0] -= A[0][0]*v;
|
A[1][0] -= A[0][0]*v;
|
||||||
|
@ -820,7 +820,7 @@ void SContour::OffsetInto(SContour *dest, double r) {
|
||||||
if(thetan < thetap && (thetap - thetan) > PI) {
|
if(thetan < thetap && (thetap - thetan) > PI) {
|
||||||
thetan += 2*PI;
|
thetan += 2*PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fabs(thetan - thetap) < (1*PI)/180) {
|
if(fabs(thetan - thetap) < (1*PI)/180) {
|
||||||
Vector p = { b.x - r*sin(thetap), b.y + r*cos(thetap), 0 };
|
Vector p = { b.x - r*sin(thetap), b.y + r*cos(thetap), 0 };
|
||||||
dest->AddPoint(p);
|
dest->AddPoint(p);
|
||||||
|
@ -846,7 +846,7 @@ void SContour::OffsetInto(SContour *dest, double r) {
|
||||||
ndx = cos(thetan);
|
ndx = cos(thetan);
|
||||||
ndy = sin(thetan);
|
ndy = sin(thetan);
|
||||||
|
|
||||||
IntersectionOfLines(px0, py0, pdx, pdy,
|
IntersectionOfLines(px0, py0, pdx, pdy,
|
||||||
nx0, ny0, ndx, ndy,
|
nx0, ny0, ndx, ndy,
|
||||||
&x, &y);
|
&x, &y);
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ public:
|
||||||
bool construction;
|
bool construction;
|
||||||
NameStr str;
|
NameStr str;
|
||||||
NameStr font;
|
NameStr font;
|
||||||
|
|
||||||
static hParam AddParam(ParamList *param, hParam hp);
|
static hParam AddParam(ParamList *param, hParam hp);
|
||||||
void Generate(EntityList *entity, ParamList *param);
|
void Generate(EntityList *entity, ParamList *param);
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ bool SolveSpace::OkayToStartNewFile(void) {
|
||||||
|
|
||||||
case SAVE_CANCEL:
|
case SAVE_CANCEL:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default: oops(); break;
|
default: oops(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ void SolveSpace::MenuFile(int id) {
|
||||||
case GraphicsWindow::MNU_EXPORT_PNG: {
|
case GraphicsWindow::MNU_EXPORT_PNG: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, PNG_EXT, PNG_PATTERN)) break;
|
if(!GetSaveFile(exportFile, PNG_EXT, PNG_PATTERN)) break;
|
||||||
SS.ExportAsPngTo(exportFile);
|
SS.ExportAsPngTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,28 +441,28 @@ void SolveSpace::MenuFile(int id) {
|
||||||
"text window.");
|
"text window.");
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.ExportViewOrWireframeTo(exportFile, false);
|
SS.ExportViewOrWireframeTo(exportFile, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_WIREFRAME: {
|
case GraphicsWindow::MNU_EXPORT_WIREFRAME: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, V3D_EXT, V3D_PATTERN)) break;
|
if(!GetSaveFile(exportFile, V3D_EXT, V3D_PATTERN)) break;
|
||||||
SS.ExportViewOrWireframeTo(exportFile, true);
|
SS.ExportViewOrWireframeTo(exportFile, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_SECTION: {
|
case GraphicsWindow::MNU_EXPORT_SECTION: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, VEC_EXT, VEC_PATTERN)) break;
|
if(!GetSaveFile(exportFile, VEC_EXT, VEC_PATTERN)) break;
|
||||||
SS.ExportSectionTo(exportFile);
|
SS.ExportSectionTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_MESH: {
|
case GraphicsWindow::MNU_EXPORT_MESH: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(!GetSaveFile(exportFile, MESH_EXT, MESH_PATTERN)) break;
|
if(!GetSaveFile(exportFile, MESH_EXT, MESH_PATTERN)) break;
|
||||||
SS.ExportMeshTo(exportFile);
|
SS.ExportMeshTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ void SolveSpace::MenuFile(int id) {
|
||||||
if(!GetSaveFile(exportFile, SRF_EXT, SRF_PATTERN)) break;
|
if(!GetSaveFile(exportFile, SRF_EXT, SRF_PATTERN)) break;
|
||||||
StepFileWriter sfw;
|
StepFileWriter sfw;
|
||||||
ZERO(&sfw);
|
ZERO(&sfw);
|
||||||
sfw.ExportSurfacesTo(exportFile);
|
sfw.ExportSurfacesTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
SMesh *m = &(g->displayMesh);
|
SMesh *m = &(g->displayMesh);
|
||||||
SKdNode *root = SKdNode::From(m);
|
SKdNode *root = SKdNode::From(m);
|
||||||
bool inters, leaks;
|
bool inters, leaks;
|
||||||
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
||||||
SKdNode::NAKED_OR_SELF_INTER_EDGES, true, &inters, &leaks);
|
SKdNode::NAKED_OR_SELF_INTER_EDGES, true, &inters, &leaks);
|
||||||
|
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
|
@ -574,7 +574,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_VOLUME: {
|
case GraphicsWindow::MNU_VOLUME: {
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
|
|
||||||
double vol = 0;
|
double vol = 0;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
|
@ -604,7 +604,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
|
|
||||||
// Triangles on edge don't contribute
|
// Triangles on edge don't contribute
|
||||||
if(fabs(n.z) < LENGTH_EPS) continue;
|
if(fabs(n.z) < LENGTH_EPS) continue;
|
||||||
|
|
||||||
// The plane has equation p dot n = a dot n
|
// The plane has equation p dot n = a dot n
|
||||||
double d = (tr.a).Dot(n);
|
double d = (tr.a).Dot(n);
|
||||||
// nx*x + ny*y + nz*z = d
|
// nx*x + ny*y + nz*z = d
|
||||||
|
@ -613,10 +613,10 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
|
|
||||||
double mac = tr.c.y/tr.c.x, mbc = (tr.c.y - tr.b.y)/tr.c.x;
|
double mac = tr.c.y/tr.c.x, mbc = (tr.c.y - tr.b.y)/tr.c.x;
|
||||||
double xc = tr.c.x, yb = tr.b.y;
|
double xc = tr.c.x, yb = tr.b.y;
|
||||||
|
|
||||||
// I asked Maple for
|
// I asked Maple for
|
||||||
// int(int(A*x + B*y +C, y=mac*x..(mbc*x + yb)), x=0..xc);
|
// int(int(A*x + B*y +C, y=mac*x..(mbc*x + yb)), x=0..xc);
|
||||||
double integral =
|
double integral =
|
||||||
(1.0/3)*(
|
(1.0/3)*(
|
||||||
A*(mbc-mac)+
|
A*(mbc-mac)+
|
||||||
(1.0/2)*B*(mbc*mbc-mac*mac)
|
(1.0/2)*B*(mbc*mbc-mac*mac)
|
||||||
|
@ -687,7 +687,7 @@ void SolveSpace::MenuAnalyze(int id) {
|
||||||
Error("Bad selection for trace; select a single point.");
|
Error("Bad selection for trace; select a single point.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_STOP_TRACING: {
|
case GraphicsWindow::MNU_STOP_TRACING: {
|
||||||
char exportFile[MAX_PATH] = "";
|
char exportFile[MAX_PATH] = "";
|
||||||
if(GetSaveFile(exportFile, CSV_EXT, CSV_PATTERN)) {
|
if(GetSaveFile(exportFile, CSV_EXT, CSV_PATTERN)) {
|
||||||
|
@ -722,7 +722,7 @@ void SolveSpace::MenuHelp(int id) {
|
||||||
case GraphicsWindow::MNU_WEBSITE:
|
case GraphicsWindow::MNU_WEBSITE:
|
||||||
OpenWebsite("http://solvespace.com/helpmenu");
|
OpenWebsite("http://solvespace.com/helpmenu");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_ABOUT:
|
case GraphicsWindow::MNU_ABOUT:
|
||||||
Message(
|
Message(
|
||||||
"This is SolveSpace version " PACKAGE_VERSION ".\n"
|
"This is SolveSpace version " PACKAGE_VERSION ".\n"
|
||||||
|
|
|
@ -473,7 +473,7 @@ public:
|
||||||
void LoadGlyph(int index);
|
void LoadGlyph(int index);
|
||||||
bool LoadFontFromFile(bool nameOnly);
|
bool LoadFontFromFile(bool nameOnly);
|
||||||
const char *FontFileBaseName(void);
|
const char *FontFileBaseName(void);
|
||||||
|
|
||||||
void Flush(void);
|
void Flush(void);
|
||||||
void Handle(int *dx, int x, int y, bool onCurve);
|
void Handle(int *dx, int x, int y, bool onCurve);
|
||||||
void PlotCharacter(int *dx, int c, double spacing);
|
void PlotCharacter(int *dx, int c, double spacing);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Top-level functions to compute the Boolean union or difference between
|
// Top-level functions to compute the Boolean union or difference between
|
||||||
// two shells of rational polynomial surfaces.
|
// two shells of rational polynomial surfaces.
|
||||||
//
|
//
|
||||||
// Copyright 2008-2013 Jonathan Westhues.
|
// Copyright 2008-2013 Jonathan Westhues.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
@ -29,7 +29,7 @@ static int ByTAlongLine(const void *av, const void *bv)
|
||||||
{
|
{
|
||||||
SInter *a = (SInter *)av,
|
SInter *a = (SInter *)av,
|
||||||
*b = (SInter *)bv;
|
*b = (SInter *)bv;
|
||||||
|
|
||||||
double ta = (a->p.Minus(LineStart)).DivPivoting(LineDirection),
|
double ta = (a->p.Minus(LineStart)).DivPivoting(LineDirection),
|
||||||
tb = (b->p.Minus(LineStart)).DivPivoting(LineDirection);
|
tb = (b->p.Minus(LineStart)).DivPivoting(LineDirection);
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
||||||
LineStart = prev.p;
|
LineStart = prev.p;
|
||||||
LineDirection = (p->p).Minus(prev.p);
|
LineDirection = (p->p).Minus(prev.p);
|
||||||
qsort(il.elem, il.n, sizeof(il.elem[0]), ByTAlongLine);
|
qsort(il.elem, il.n, sizeof(il.elem[0]), ByTAlongLine);
|
||||||
|
|
||||||
// And now uses the intersections to generate our split pwl edge(s)
|
// And now uses the intersections to generate our split pwl edge(s)
|
||||||
Vector prev = Vector::From(VERY_POSITIVE, 0, 0);
|
Vector prev = Vector::From(VERY_POSITIVE, 0, 0);
|
||||||
for(pi = il.First(); pi; pi = il.NextAfter(pi)) {
|
for(pi = il.First(); pi; pi = il.NextAfter(pi)) {
|
||||||
|
@ -131,7 +131,7 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) {
|
void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) {
|
||||||
SCurve *sc;
|
SCurve *sc;
|
||||||
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
||||||
SCurve scn = sc->MakeCopySplitAgainst(agnst, NULL,
|
SCurve scn = sc->MakeCopySplitAgainst(agnst, NULL,
|
||||||
|
@ -147,7 +147,7 @@ void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) {
|
||||||
|
|
||||||
void SSurface::TrimFromEdgeList(SEdgeList *el, bool asUv) {
|
void SSurface::TrimFromEdgeList(SEdgeList *el, bool asUv) {
|
||||||
el->l.ClearTags();
|
el->l.ClearTags();
|
||||||
|
|
||||||
STrimBy stb;
|
STrimBy stb;
|
||||||
ZERO(&stb);
|
ZERO(&stb);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -155,7 +155,7 @@ void SSurface::TrimFromEdgeList(SEdgeList *el, bool asUv) {
|
||||||
SEdge *se;
|
SEdge *se;
|
||||||
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
||||||
if(se->tag) continue;
|
if(se->tag) continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!se) break;
|
if(!se) break;
|
||||||
se->tag = 1;
|
se->tag = 1;
|
||||||
|
@ -306,7 +306,7 @@ static const char *REGION(int d) {
|
||||||
// point within the avoid list ever occurs in the middle of a chain. And we
|
// point within the avoid list ever occurs in the middle of a chain. And we
|
||||||
// delete the edges in that chain from our source list.
|
// delete the edges in that chain from our source list.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest,
|
void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest,
|
||||||
SPointList *avoid)
|
SPointList *avoid)
|
||||||
{
|
{
|
||||||
if(src->l.n < 1) oops();
|
if(src->l.n < 1) oops();
|
||||||
|
@ -464,7 +464,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
} else {
|
} else {
|
||||||
if(sc->surfB.v != h.v || sc->surfA.v != ss->h.v) continue;
|
if(sc->surfB.v != h.v || sc->surfA.v != ss->h.v) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < sc->pts.n; i++) {
|
for(i = 1; i < sc->pts.n; i++) {
|
||||||
Vector a = sc->pts.elem[i-1].p,
|
Vector a = sc->pts.elem[i-1].p,
|
||||||
|
@ -492,7 +492,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
if(type == SShell::AS_DIFFERENCE && !opA) bkwds = !bkwds;
|
if(type == SShell::AS_DIFFERENCE && !opA) bkwds = !bkwds;
|
||||||
if(bkwds) {
|
if(bkwds) {
|
||||||
inter.AddEdge(tb, ta, sc->h.v, 1);
|
inter.AddEdge(tb, ta, sc->h.v, 1);
|
||||||
} else {
|
} else {
|
||||||
inter.AddEdge(ta, tb, sc->h.v, 0);
|
inter.AddEdge(ta, tb, sc->h.v, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,10 +552,10 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
outdir_orig = SShell::OUTSIDE;
|
outdir_orig = SShell::OUTSIDE;
|
||||||
|
|
||||||
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
|
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
|
||||||
ret.PointAt(auv), ret.PointAt(buv), pt,
|
ret.PointAt(auv), ret.PointAt(buv), pt,
|
||||||
enin, enout, surfn);
|
enin, enout, surfn);
|
||||||
|
|
||||||
if(KeepEdge(type, opA, indir_shell, outdir_shell,
|
if(KeepEdge(type, opA, indir_shell, outdir_shell,
|
||||||
indir_orig, outdir_orig))
|
indir_orig, outdir_orig))
|
||||||
{
|
{
|
||||||
for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) {
|
for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) {
|
||||||
|
@ -572,7 +572,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
|
|
||||||
// Any edge in the chain, same as above.
|
// Any edge in the chain, same as above.
|
||||||
se = &(chain.l.elem[chain.l.n/2]);
|
se = &(chain.l.elem[chain.l.n/2]);
|
||||||
|
|
||||||
Point2d auv = (se->a).ProjectXy(),
|
Point2d auv = (se->a).ProjectXy(),
|
||||||
buv = (se->b).ProjectXy();
|
buv = (se->b).ProjectXy();
|
||||||
|
|
||||||
|
@ -586,10 +586,10 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
TagByClassifiedEdge(c_this, &indir_orig, &outdir_orig);
|
TagByClassifiedEdge(c_this, &indir_orig, &outdir_orig);
|
||||||
|
|
||||||
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
|
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
|
||||||
ret.PointAt(auv), ret.PointAt(buv), pt,
|
ret.PointAt(auv), ret.PointAt(buv), pt,
|
||||||
enin, enout, surfn);
|
enin, enout, surfn);
|
||||||
|
|
||||||
if(KeepEdge(type, opA, indir_shell, outdir_shell,
|
if(KeepEdge(type, opA, indir_shell, outdir_shell,
|
||||||
indir_orig, outdir_orig))
|
indir_orig, outdir_orig))
|
||||||
{
|
{
|
||||||
for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) {
|
for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) {
|
||||||
|
@ -660,7 +660,7 @@ void SShell::CleanupAfterBoolean(void) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// All curves contain handles to the two surfaces that they trim. After a
|
// All curves contain handles to the two surfaces that they trim. After a
|
||||||
// Boolean or assembly, we must rewrite those handles to refer to the curves
|
// Boolean or assembly, we must rewrite those handles to refer to the curves
|
||||||
// by their new IDs.
|
// by their new IDs.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) {
|
void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) {
|
||||||
SCurve *sc;
|
SCurve *sc;
|
||||||
|
@ -684,7 +684,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
|
||||||
Quaternion q = Quaternion::IDENTITY;
|
Quaternion q = Quaternion::IDENTITY;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
SShell *ab;
|
SShell *ab;
|
||||||
|
|
||||||
// First, copy over all the curves. Note which shell (a or b) each curve
|
// First, copy over all the curves. Note which shell (a or b) each curve
|
||||||
// came from, but assign it a new ID.
|
// came from, but assign it a new ID.
|
||||||
SCurve *c, cn;
|
SCurve *c, cn;
|
||||||
|
@ -743,7 +743,7 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, int type) {
|
||||||
|
|
||||||
sc->RemoveShortSegments(srfA, srfB);
|
sc->RemoveShortSegments(srfA, srfB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// And clean up the piecewise linear things we made as a calculation aid
|
// And clean up the piecewise linear things we made as a calculation aid
|
||||||
a->CleanupAfterBoolean();
|
a->CleanupAfterBoolean();
|
||||||
b->CleanupAfterBoolean();
|
b->CleanupAfterBoolean();
|
||||||
|
@ -801,7 +801,7 @@ static int ByLength(const void *av, const void *bv)
|
||||||
{
|
{
|
||||||
SEdge *a = (SEdge *)av,
|
SEdge *a = (SEdge *)av,
|
||||||
*b = (SEdge *)bv;
|
*b = (SEdge *)bv;
|
||||||
|
|
||||||
double la = (a->a).Minus(a->b).Magnitude(),
|
double la = (a->a).Minus(a->b).Magnitude(),
|
||||||
lb = (b->a).Minus(b->b).Magnitude();
|
lb = (b->a).Minus(b->b).Magnitude();
|
||||||
|
|
||||||
|
@ -846,7 +846,7 @@ void SBspUv::ScalePoints(Point2d *pt, Point2d *a, Point2d *b, SSurface *srf) {
|
||||||
a ->x *= mu; a ->y *= mv;
|
a ->x *= mu; a ->y *= mv;
|
||||||
b ->x *= mu; b ->y *= mv;
|
b ->x *= mu; b ->y *= mv;
|
||||||
}
|
}
|
||||||
double SBspUv::ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b,
|
double SBspUv::ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b,
|
||||||
SSurface *srf)
|
SSurface *srf)
|
||||||
{
|
{
|
||||||
ScalePoints(&pt, &a, &b, srf);
|
ScalePoints(&pt, &a, &b, srf);
|
||||||
|
|
|
@ -156,7 +156,7 @@ bool SBezier::IsCircle(Vector axis, Vector *center, double *r) {
|
||||||
Point2d c2 = center->Project2d(u, v),
|
Point2d c2 = center->Project2d(u, v),
|
||||||
pa2 = (ctrl[0]).Project2d(u, v).Minus(c2),
|
pa2 = (ctrl[0]).Project2d(u, v).Minus(c2),
|
||||||
pb2 = (ctrl[2]).Project2d(u, v).Minus(c2);
|
pb2 = (ctrl[2]).Project2d(u, v).Minus(c2);
|
||||||
|
|
||||||
double thetaa = atan2(pa2.y, pa2.x), // in fact always zero due to csys
|
double thetaa = atan2(pa2.y, pa2.x), // in fact always zero due to csys
|
||||||
thetab = atan2(pb2.y, pb2.x),
|
thetab = atan2(pb2.y, pb2.x),
|
||||||
dtheta = WRAP_NOT_0(thetab - thetaa, 2*PI);
|
dtheta = WRAP_NOT_0(thetab - thetaa, 2*PI);
|
||||||
|
@ -398,7 +398,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
|
||||||
|
|
||||||
if(sbl->l.n < 1) return loop;
|
if(sbl->l.n < 1) return loop;
|
||||||
sbl->l.ClearTags();
|
sbl->l.ClearTags();
|
||||||
|
|
||||||
SBezier *first = &(sbl->l.elem[0]);
|
SBezier *first = &(sbl->l.elem[0]);
|
||||||
first->tag = 1;
|
first->tag = 1;
|
||||||
loop.l.Add(first);
|
loop.l.Add(first);
|
||||||
|
@ -438,7 +438,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
|
||||||
}
|
}
|
||||||
if(hanging.Equals(start)) {
|
if(hanging.Equals(start)) {
|
||||||
*allClosed = true;
|
*allClosed = true;
|
||||||
} else {
|
} else {
|
||||||
// We ran out of edges without forming a closed loop.
|
// We ran out of edges without forming a closed loop.
|
||||||
errorAt->a = hanging;
|
errorAt->a = hanging;
|
||||||
errorAt->b = start;
|
errorAt->b = start;
|
||||||
|
@ -691,7 +691,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
|
||||||
inner->tag = USED_LOOP;
|
inner->tag = USED_LOOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outerAndInners.point = srfuv->PointAt(0, 0);
|
outerAndInners.point = srfuv->PointAt(0, 0);
|
||||||
outerAndInners.normal = srfuv->NormalAt(0, 0);
|
outerAndInners.normal = srfuv->NormalAt(0, 0);
|
||||||
l.Add(&outerAndInners);
|
l.Add(&outerAndInners);
|
||||||
|
@ -753,7 +753,7 @@ SCurve SCurve::FromTransformationOf(SCurve *a,
|
||||||
ret.exact = (a->exact).TransformedBy(t, q, scale);
|
ret.exact = (a->exact).TransformedBy(t, q, scale);
|
||||||
ret.surfA = a->surfA;
|
ret.surfA = a->surfA;
|
||||||
ret.surfB = a->surfB;
|
ret.surfB = a->surfB;
|
||||||
|
|
||||||
SCurvePt *p;
|
SCurvePt *p;
|
||||||
for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) {
|
for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) {
|
||||||
SCurvePt pp = *p;
|
SCurvePt pp = *p;
|
||||||
|
|
|
@ -137,7 +137,7 @@ void SBezier::ClosestPointTo(Vector p, double *t, bool converge) {
|
||||||
double res = (deg <= 2) ? 7.0 : 20.0;
|
double res = (deg <= 2) ? 7.0 : 20.0;
|
||||||
for(i = 0; i < (int)res; i++) {
|
for(i = 0; i < (int)res; i++) {
|
||||||
double tryt = (i/res);
|
double tryt = (i/res);
|
||||||
|
|
||||||
Vector tryp = PointAt(tryt);
|
Vector tryp = PointAt(tryt);
|
||||||
double d = (tryp.Minus(p)).Magnitude();
|
double d = (tryp.Minus(p)).Magnitude();
|
||||||
if(d < minDist) {
|
if(d < minDist) {
|
||||||
|
@ -168,7 +168,7 @@ bool SBezier::PointOnThisAndCurve(SBezier *sbb, Vector *p) {
|
||||||
sbb ->ClosestPointTo(*p, &tb, false);
|
sbb ->ClosestPointTo(*p, &tb, false);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 20; i++) {
|
for(i = 0; i < 20; i++) {
|
||||||
Vector pa = this->PointAt(ta),
|
Vector pa = this->PointAt(ta),
|
||||||
pb = sbb ->PointAt(tb),
|
pb = sbb ->PointAt(tb),
|
||||||
da = this->TangentAt(ta),
|
da = this->TangentAt(ta),
|
||||||
|
@ -178,7 +178,7 @@ bool SBezier::PointOnThisAndCurve(SBezier *sbb, Vector *p) {
|
||||||
*p = pa;
|
*p = pa;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double tta, ttb;
|
double tta, ttb;
|
||||||
Vector::ClosestPointBetweenLines(pa, da, pb, db, &tta, &ttb);
|
Vector::ClosestPointBetweenLines(pa, da, pb, db, &tta, &ttb);
|
||||||
ta += tta;
|
ta += tta;
|
||||||
|
@ -413,7 +413,7 @@ void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool converge) {
|
||||||
for(i = 0; i < res; i++) {
|
for(i = 0; i < res; i++) {
|
||||||
for(j = 0; j < res; j++) {
|
for(j = 0; j < res; j++) {
|
||||||
double tryu = (i + 0.5)/res, tryv = (j + 0.5)/res;
|
double tryu = (i + 0.5)/res, tryv = (j + 0.5)/res;
|
||||||
|
|
||||||
Vector tryp = PointAt(tryu, tryv);
|
Vector tryp = PointAt(tryu, tryv);
|
||||||
double d = (tryp.Minus(p)).Magnitude();
|
double d = (tryp.Minus(p)).Magnitude();
|
||||||
if(d < minDist) {
|
if(d < minDist) {
|
||||||
|
@ -450,7 +450,7 @@ bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool converge)
|
||||||
|
|
||||||
Vector tu, tv;
|
Vector tu, tv;
|
||||||
TangentsAt(*u, *v, &tu, &tv);
|
TangentsAt(*u, *v, &tu, &tv);
|
||||||
|
|
||||||
// Project the point into a plane through p0, with basis tu, tv; a
|
// Project the point into a plane through p0, with basis tu, tv; a
|
||||||
// second-order thing would converge faster but needs second
|
// second-order thing would converge faster but needs second
|
||||||
// derivatives.
|
// derivatives.
|
||||||
|
@ -476,7 +476,7 @@ bool SSurface::PointIntersectingLine(Vector p0, Vector p1, double *u, double *v)
|
||||||
Vector pi, p, tu, tv;
|
Vector pi, p, tu, tv;
|
||||||
p = PointAt(*u, *v);
|
p = PointAt(*u, *v);
|
||||||
TangentsAt(*u, *v, &tu, &tv);
|
TangentsAt(*u, *v, &tu, &tv);
|
||||||
|
|
||||||
Vector n = (tu.Cross(tv)).WithMagnitude(1);
|
Vector n = (tu.Cross(tv)).WithMagnitude(1);
|
||||||
double d = p.Dot(n);
|
double d = p.Dot(n);
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ Vector SSurface::ClosestPointOnThisAndSurface(SSurface *srf2, Vector p) {
|
||||||
|
|
||||||
Vector p0 = Vector::AtIntersectionOfPlanes(n[0], d[0], n[1], d[1]),
|
Vector p0 = Vector::AtIntersectionOfPlanes(n[0], d[0], n[1], d[1]),
|
||||||
dp = (n[0]).Cross(n[1]);
|
dp = (n[0]).Cross(n[1]);
|
||||||
|
|
||||||
Vector pc = p.ClosestPointOnLine(p0, dp);
|
Vector pc = p.ClosestPointOnLine(p0, dp);
|
||||||
|
|
||||||
// Adjust our guess and iterate
|
// Adjust our guess and iterate
|
||||||
|
@ -569,7 +569,7 @@ void SSurface::PointOnSurfaces(SSurface *s1, SSurface *s2,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a = b and b = c, then does a = c? No, it doesn't.
|
// If a = b and b = c, then does a = c? No, it doesn't.
|
||||||
if((p[0]).Equals(p[1], RATPOLY_EPS) &&
|
if((p[0]).Equals(p[1], RATPOLY_EPS) &&
|
||||||
(p[1]).Equals(p[2], RATPOLY_EPS) &&
|
(p[1]).Equals(p[2], RATPOLY_EPS) &&
|
||||||
(p[2]).Equals(p[0], RATPOLY_EPS))
|
(p[2]).Equals(p[0], RATPOLY_EPS))
|
||||||
{
|
{
|
||||||
|
|
|
@ -196,7 +196,7 @@ void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
||||||
// Test if the line intersects our axis-aligned bounding box; if no, then
|
// Test if the line intersects our axis-aligned bounding box; if no, then
|
||||||
// no possibility of an intersection
|
// no possibility of an intersection
|
||||||
if(LineEntirelyOutsideBbox(a, b, segment)) return;
|
if(LineEntirelyOutsideBbox(a, b, segment)) return;
|
||||||
|
|
||||||
if(*cnt > 2000) {
|
if(*cnt > 2000) {
|
||||||
dbp("!!! too many subdivisions (level=%d)!", *level);
|
dbp("!!! too many subdivisions (level=%d)!", *level);
|
||||||
dbp("degm = %d degn = %d", degm, degn);
|
dbp("degm = %d degn = %d", degm, degn);
|
||||||
|
@ -359,7 +359,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
||||||
if(seg && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) {
|
if(seg && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And that it lies inside our trim region
|
// And that it lies inside our trim region
|
||||||
Point2d dummy = { 0, 0 };
|
Point2d dummy = { 0, 0 };
|
||||||
int c = bsp->ClassifyPoint(puv, dummy, this);
|
int c = bsp->ClassifyPoint(puv, dummy, this);
|
||||||
|
@ -423,7 +423,7 @@ int SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
bool SShell::ClassifyEdge(int *indir, int *outdir,
|
bool SShell::ClassifyEdge(int *indir, int *outdir,
|
||||||
Vector ea, Vector eb,
|
Vector ea, Vector eb,
|
||||||
Vector p,
|
Vector p,
|
||||||
Vector edge_n_in, Vector edge_n_out, Vector surf_n)
|
Vector edge_n_in, Vector edge_n_out, Vector surf_n)
|
||||||
{
|
{
|
||||||
List<SInter> l;
|
List<SInter> l;
|
||||||
|
@ -556,7 +556,7 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
|
||||||
|
|
||||||
AllPointsIntersecting(
|
AllPointsIntersecting(
|
||||||
p.Minus(ray), p.Plus(ray), &l, false, true, false);
|
p.Minus(ray), p.Plus(ray), &l, false, true, false);
|
||||||
|
|
||||||
// no intersections means it's outside
|
// no intersections means it's outside
|
||||||
*indir = OUTSIDE;
|
*indir = OUTSIDE;
|
||||||
*outdir = OUTSIDE;
|
*outdir = OUTSIDE;
|
||||||
|
|
|
@ -123,14 +123,14 @@ SSurface SSurface::FromPlane(Vector pt, Vector u, Vector v) {
|
||||||
ret.degm = 1;
|
ret.degm = 1;
|
||||||
ret.degn = 1;
|
ret.degn = 1;
|
||||||
|
|
||||||
ret.weight[0][0] = ret.weight[0][1] = 1;
|
ret.weight[0][0] = ret.weight[0][1] = 1;
|
||||||
ret.weight[1][0] = ret.weight[1][1] = 1;
|
ret.weight[1][0] = ret.weight[1][1] = 1;
|
||||||
|
|
||||||
ret.ctrl[0][0] = pt;
|
ret.ctrl[0][0] = pt;
|
||||||
ret.ctrl[0][1] = pt.Plus(u);
|
ret.ctrl[0][1] = pt.Plus(u);
|
||||||
ret.ctrl[1][0] = pt.Plus(v);
|
ret.ctrl[1][0] = pt.Plus(v);
|
||||||
ret.ctrl[1][1] = pt.Plus(v).Plus(u);
|
ret.ctrl[1][1] = pt.Plus(v).Plus(u);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
|
||||||
if(el.AssemblePolygon(&poly, NULL, true)) {
|
if(el.AssemblePolygon(&poly, NULL, true)) {
|
||||||
int i, start = sm->l.n;
|
int i, start = sm->l.n;
|
||||||
if(degm == 1 && degn == 1) {
|
if(degm == 1 && degn == 1) {
|
||||||
// A surface with curvature along one direction only; so
|
// A surface with curvature along one direction only; so
|
||||||
// choose the triangulation with chords that lie as much
|
// choose the triangulation with chords that lie as much
|
||||||
// as possible within the surface. And since the trim curves
|
// as possible within the surface. And since the trim curves
|
||||||
// have been pwl'd to within the desired chord tol, that will
|
// have been pwl'd to within the desired chord tol, that will
|
||||||
|
@ -522,7 +522,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||||
s1.color = color;
|
s1.color = color;
|
||||||
hSSurface hs0 = surface.AddAndAssignId(&s0),
|
hSSurface hs0 = surface.AddAndAssignId(&s0),
|
||||||
hs1 = surface.AddAndAssignId(&s1);
|
hs1 = surface.AddAndAssignId(&s1);
|
||||||
|
|
||||||
// Now go through the input curves. For each one, generate its surface
|
// Now go through the input curves. For each one, generate its surface
|
||||||
// of extrusion, its two translated trim curves, and one trim line. We
|
// of extrusion, its two translated trim curves, and one trim line. We
|
||||||
// go through by loops so that we can assign the lines correctly.
|
// go through by loops so that we can assign the lines correctly.
|
||||||
|
@ -653,7 +653,7 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
||||||
for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
|
for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) {
|
||||||
Revolved revs;
|
Revolved revs;
|
||||||
for(j = 0; j < 4; j++) {
|
for(j = 0; j < 4; j++) {
|
||||||
if(sb->deg == 1 &&
|
if(sb->deg == 1 &&
|
||||||
(sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
|
(sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS &&
|
||||||
(sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS)
|
(sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS)
|
||||||
{
|
{
|
||||||
|
@ -705,7 +705,7 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
||||||
|
|
||||||
// And if this input curve and the one after it both generated
|
// And if this input curve and the one after it both generated
|
||||||
// surfaces, then trim both of those by the appropriate
|
// surfaces, then trim both of those by the appropriate
|
||||||
// circle.
|
// circle.
|
||||||
if(revs.d[j].v && revsp.d[j].v) {
|
if(revs.d[j].v && revsp.d[j].v) {
|
||||||
SSurface *ss = surface.FindById(revs.d[j]);
|
SSurface *ss = surface.FindById(revs.d[j]);
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ public:
|
||||||
hSSurface surfA;
|
hSSurface surfA;
|
||||||
hSSurface surfB;
|
hSSurface surfB;
|
||||||
|
|
||||||
static SCurve FromTransformationOf(SCurve *a, Vector t, Quaternion q,
|
static SCurve FromTransformationOf(SCurve *a, Vector t, Quaternion q,
|
||||||
double scale);
|
double scale);
|
||||||
SCurve MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
SCurve MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
||||||
SSurface *srfA, SSurface *srfB);
|
SSurface *srfA, SSurface *srfB);
|
||||||
|
@ -285,7 +285,7 @@ public:
|
||||||
SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b,
|
SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b,
|
||||||
SShell *into, int type);
|
SShell *into, int type);
|
||||||
void TrimFromEdgeList(SEdgeList *el, bool asUv);
|
void TrimFromEdgeList(SEdgeList *el, bool asUv);
|
||||||
void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
SShell *into);
|
SShell *into);
|
||||||
void AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
|
void AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
|
||||||
SShell *agnstA, SShell *agnstB, SShell *into);
|
SShell *agnstA, SShell *agnstB, SShell *into);
|
||||||
|
@ -398,7 +398,7 @@ public:
|
||||||
int ClassifyRegion(Vector edge_n, Vector inter_surf_n, Vector edge_surf_n);
|
int ClassifyRegion(Vector edge_n, Vector inter_surf_n, Vector edge_surf_n);
|
||||||
bool ClassifyEdge(int *indir, int *outdir,
|
bool ClassifyEdge(int *indir, int *outdir,
|
||||||
Vector ea, Vector eb,
|
Vector ea, Vector eb,
|
||||||
Vector p,
|
Vector p,
|
||||||
Vector edge_n_in, Vector edge_n_out, Vector surf_n);
|
Vector edge_n_in, Vector edge_n_out, Vector surf_n);
|
||||||
|
|
||||||
void MakeFromCopyOf(SShell *a);
|
void MakeFromCopyOf(SShell *a);
|
||||||
|
|
|
@ -56,7 +56,7 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
|
||||||
sc.Clear();
|
sc.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if the curve lies entirely outside one of the
|
// Test if the curve lies entirely outside one of the
|
||||||
SCurvePt *scpt;
|
SCurvePt *scpt;
|
||||||
bool withinA = false, withinB = false;
|
bool withinA = false, withinB = false;
|
||||||
for(scpt = split.pts.First(); scpt; scpt = split.pts.NextAfter(scpt)) {
|
for(scpt = split.pts.First(); scpt; scpt = split.pts.NextAfter(scpt)) {
|
||||||
|
@ -105,7 +105,7 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
|
||||||
into->curve.AddAndAssignId(&split);
|
into->curve.AddAndAssignId(&split);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
SShell *into)
|
SShell *into)
|
||||||
{
|
{
|
||||||
Vector amax, amin, bmax, bmin;
|
Vector amax, amin, bmax, bmin;
|
||||||
|
@ -220,7 +220,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
ZERO(&inters);
|
ZERO(&inters);
|
||||||
sext->AllPointsIntersecting(
|
sext->AllPointsIntersecting(
|
||||||
p0, p0.Plus(dp), &inters, false, false, true);
|
p0, p0.Plus(dp), &inters, false, false, true);
|
||||||
|
|
||||||
SInter *si;
|
SInter *si;
|
||||||
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
||||||
Vector al = along.ScaledBy(0.5);
|
Vector al = along.ScaledBy(0.5);
|
||||||
|
@ -244,14 +244,14 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
|
|
||||||
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
|
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
|
||||||
}
|
}
|
||||||
} else if(isExtdt && isExtdb &&
|
} else if(isExtdt && isExtdb &&
|
||||||
sqrt(fabs(alongt.Dot(alongb))) >
|
sqrt(fabs(alongt.Dot(alongb))) >
|
||||||
sqrt(alongt.Magnitude() * alongb.Magnitude()) - LENGTH_EPS)
|
sqrt(alongt.Magnitude() * alongb.Magnitude()) - LENGTH_EPS)
|
||||||
{
|
{
|
||||||
// Two surfaces of extrusion along the same axis. So they might
|
// Two surfaces of extrusion along the same axis. So they might
|
||||||
// intersect along some number of lines parallel to the axis.
|
// intersect along some number of lines parallel to the axis.
|
||||||
Vector axis = alongt.WithMagnitude(1);
|
Vector axis = alongt.WithMagnitude(1);
|
||||||
|
|
||||||
List<SInter> inters;
|
List<SInter> inters;
|
||||||
ZERO(&inters);
|
ZERO(&inters);
|
||||||
List<Vector> lv;
|
List<Vector> lv;
|
||||||
|
@ -403,7 +403,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
ClosestPointTo(start, &pa);
|
ClosestPointTo(start, &pa);
|
||||||
b->ClosestPointTo(start, &pb);
|
b->ClosestPointTo(start, &pb);
|
||||||
|
|
||||||
Vector na = NormalAt(pa).WithMagnitude(1),
|
Vector na = NormalAt(pa).WithMagnitude(1),
|
||||||
nb = b->NormalAt(pb).WithMagnitude(1);
|
nb = b->NormalAt(pb).WithMagnitude(1);
|
||||||
|
|
||||||
if(a == 0) {
|
if(a == 0) {
|
||||||
|
@ -496,7 +496,7 @@ bool SSurface::CoincidentWithPlane(Vector n, double d) {
|
||||||
if(fabs(n.Dot(ctrl[0][1]) - d) > LENGTH_EPS) return false;
|
if(fabs(n.Dot(ctrl[0][1]) - d) > LENGTH_EPS) return false;
|
||||||
if(fabs(n.Dot(ctrl[1][0]) - d) > LENGTH_EPS) return false;
|
if(fabs(n.Dot(ctrl[1][0]) - d) > LENGTH_EPS) return false;
|
||||||
if(fabs(n.Dot(ctrl[1][1]) - d) > LENGTH_EPS) return false;
|
if(fabs(n.Dot(ctrl[1][1]) - d) > LENGTH_EPS) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ void SPolygon::UvTriangulateInto(SMesh *m, SSurface *srf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SContour::BridgeToContour(SContour *sc,
|
bool SContour::BridgeToContour(SContour *sc,
|
||||||
SEdgeList *avoidEdges, List<Vector> *avoidPts)
|
SEdgeList *avoidEdges, List<Vector> *avoidPts)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -136,7 +136,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
}
|
}
|
||||||
|
|
||||||
int thisp, scp;
|
int thisp, scp;
|
||||||
|
|
||||||
Vector a, b, *f;
|
Vector a, b, *f;
|
||||||
|
|
||||||
// First check if the contours share a point; in that case we should
|
// First check if the contours share a point; in that case we should
|
||||||
|
@ -248,7 +248,7 @@ bool SContour::IsEar(int bp, double scaledEps) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
if(i == ap || i == bp || i == cp) continue;
|
if(i == ap || i == bp || i == cp) continue;
|
||||||
|
|
||||||
Vector p = l.elem[i].p;
|
Vector p = l.elem[i].p;
|
||||||
if(p.OutsideAndNotOn(maxv, minv)) continue;
|
if(p.OutsideAndNotOn(maxv, minv)) continue;
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ bool SContour::IsEar(int bp, double scaledEps) {
|
||||||
if(p.EqualsExactly(tr.a)) continue;
|
if(p.EqualsExactly(tr.a)) continue;
|
||||||
if(p.EqualsExactly(tr.b)) continue;
|
if(p.EqualsExactly(tr.b)) continue;
|
||||||
if(p.EqualsExactly(tr.c)) continue;
|
if(p.EqualsExactly(tr.c)) continue;
|
||||||
|
|
||||||
if(tr.ContainsPointProjd(n, p)) {
|
if(tr.ContainsPointProjd(n, p)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ bool SContour::IsEar(int bp, double scaledEps) {
|
||||||
void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) {
|
void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) {
|
||||||
int ap = WRAP(bp-1, l.n),
|
int ap = WRAP(bp-1, l.n),
|
||||||
cp = WRAP(bp+1, l.n);
|
cp = WRAP(bp+1, l.n);
|
||||||
|
|
||||||
STriangle tr;
|
STriangle tr;
|
||||||
ZERO(&tr);
|
ZERO(&tr);
|
||||||
tr.a = l.elem[ap].p;
|
tr.a = l.elem[ap].p;
|
||||||
|
|
|
@ -399,7 +399,7 @@ void TextWindow::ScreenBackgroundImage(int link, uint32_t v) {
|
||||||
|
|
||||||
png_read_png(png_ptr, info_ptr,
|
png_read_png(png_ptr, info_ptr,
|
||||||
PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL);
|
PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL);
|
||||||
|
|
||||||
int w; w = (int)png_get_image_width(png_ptr, info_ptr);
|
int w; w = (int)png_get_image_width(png_ptr, info_ptr);
|
||||||
int h; h = (int)png_get_image_height(png_ptr, info_ptr);
|
int h; h = (int)png_get_image_height(png_ptr, info_ptr);
|
||||||
uint8_t **rows; rows = png_get_rows(png_ptr, info_ptr);
|
uint8_t **rows; rows = png_get_rows(png_ptr, info_ptr);
|
||||||
|
@ -450,7 +450,7 @@ void TextWindow::ShowListOfStyles(void) {
|
||||||
darkbg = !darkbg;
|
darkbg = !darkbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(true, " %Fl%Ll%fcreate a new custom style%E",
|
Printf(true, " %Fl%Ll%fcreate a new custom style%E",
|
||||||
&ScreenCreateCustomStyle);
|
&ScreenCreateCustomStyle);
|
||||||
|
|
||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
|
@ -491,7 +491,7 @@ void TextWindow::ScreenChangeStyleName(int link, uint32_t v) {
|
||||||
Style *s = Style::Get(hs);
|
Style *s = Style::Get(hs);
|
||||||
SS.TW.ShowEditControl(10, 12, s->name.str);
|
SS.TW.ShowEditControl(10, 12, s->name.str);
|
||||||
SS.TW.edit.style = hs;
|
SS.TW.edit.style = hs;
|
||||||
SS.TW.edit.meaning = EDIT_STYLE_NAME;
|
SS.TW.edit.meaning = EDIT_STYLE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWindow::ScreenDeleteStyle(int link, uint32_t v) {
|
void TextWindow::ScreenDeleteStyle(int link, uint32_t v) {
|
||||||
|
|
|
@ -289,7 +289,7 @@ bool System::NewtonSolve(int tag) {
|
||||||
|
|
||||||
if(!SolveLeastSquares()) break;
|
if(!SolveLeastSquares()) break;
|
||||||
|
|
||||||
// Take the Newton step;
|
// Take the Newton step;
|
||||||
// J(x_n) (x_{n+1} - x_n) = 0 - F(x_n)
|
// J(x_n) (x_{n+1} - x_n) = 0 - F(x_n)
|
||||||
for(i = 0; i < mat.n; i++) {
|
for(i = 0; i < mat.n; i++) {
|
||||||
Param *p = param.FindById(mat.param[i]);
|
Param *p = param.FindById(mat.param[i]);
|
||||||
|
@ -393,7 +393,7 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
|
int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
|
||||||
bool andFindBad, bool andFindFree)
|
bool andFindBad, bool andFindFree)
|
||||||
{
|
{
|
||||||
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
|
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
|
||||||
|
@ -412,7 +412,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
|
||||||
// All params and equations are assigned to group zero.
|
// All params and equations are assigned to group zero.
|
||||||
param.ClearTags();
|
param.ClearTags();
|
||||||
eq.ClearTags();
|
eq.ClearTags();
|
||||||
|
|
||||||
SolveBySubstitution();
|
SolveBySubstitution();
|
||||||
|
|
||||||
// Before solving the big system, see if we can find any equations that
|
// Before solving the big system, see if we can find any equations that
|
||||||
|
@ -522,7 +522,7 @@ didnt_converge:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return System::DIDNT_CONVERGE;
|
return System::DIDNT_CONVERGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -307,7 +307,7 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
||||||
if(g->subtype == Group::ONE_SIDED) {
|
if(g->subtype == Group::ONE_SIDED) {
|
||||||
bool skip = g->skipFirst;
|
bool skip = g->skipFirst;
|
||||||
Printf(false,
|
Printf(false,
|
||||||
"%Bd %Ftstart %f%LK%Fd%c with original%E "
|
"%Bd %Ftstart %f%LK%Fd%c with original%E "
|
||||||
"%f%Lk%Fd%c with copy #1%E",
|
"%f%Lk%Fd%c with copy #1%E",
|
||||||
&ScreenChangeGroupOption,
|
&ScreenChangeGroupOption,
|
||||||
|
|
|
@ -293,7 +293,7 @@ void TextWindow::Show(void) {
|
||||||
Printf(false, "%s", SS.GW.pending.description);
|
Printf(false, "%s", SS.GW.pending.description);
|
||||||
Printf(true, "%Fl%f%Ll(cancel operation)%E",
|
Printf(true, "%Fl%f%Ll(cancel operation)%E",
|
||||||
&TextWindow::ScreenUnselectAll);
|
&TextWindow::ScreenUnselectAll);
|
||||||
} else if((gs.n > 0 || gs.constraints > 0) &&
|
} else if((gs.n > 0 || gs.constraints > 0) &&
|
||||||
shown.screen != SCREEN_PASTE_TRANSFORMED)
|
shown.screen != SCREEN_PASTE_TRANSFORMED)
|
||||||
{
|
{
|
||||||
if(edit.meaning != EDIT_TTF_TEXT) HideEditControl();
|
if(edit.meaning != EDIT_TTF_TEXT) HideEditControl();
|
||||||
|
@ -477,17 +477,17 @@ Vector TextWindow::HsvToRgb(Vector hsv) {
|
||||||
while(hmod2 >= 2) hmod2 -= 2;
|
while(hmod2 >= 2) hmod2 -= 2;
|
||||||
double x = (1 - fabs(hmod2 - 1));
|
double x = (1 - fabs(hmod2 - 1));
|
||||||
if(hsv.x < 1) {
|
if(hsv.x < 1) {
|
||||||
rgb = Vector::From(1, x, 0);
|
rgb = Vector::From(1, x, 0);
|
||||||
} else if(hsv.x < 2) {
|
} else if(hsv.x < 2) {
|
||||||
rgb = Vector::From(x, 1, 0);
|
rgb = Vector::From(x, 1, 0);
|
||||||
} else if(hsv.x < 3) {
|
} else if(hsv.x < 3) {
|
||||||
rgb = Vector::From(0, 1, x);
|
rgb = Vector::From(0, 1, x);
|
||||||
} else if(hsv.x < 4) {
|
} else if(hsv.x < 4) {
|
||||||
rgb = Vector::From(0, x, 1);
|
rgb = Vector::From(0, x, 1);
|
||||||
} else if(hsv.x < 5) {
|
} else if(hsv.x < 5) {
|
||||||
rgb = Vector::From(x, 0, 1);
|
rgb = Vector::From(x, 0, 1);
|
||||||
} else {
|
} else {
|
||||||
rgb = Vector::From(1, 0, x);
|
rgb = Vector::From(1, 0, x);
|
||||||
}
|
}
|
||||||
double c = hsv.y*hsv.z;
|
double c = hsv.y*hsv.z;
|
||||||
double m = 1 - hsv.z;
|
double m = 1 - hsv.z;
|
||||||
|
@ -707,7 +707,7 @@ bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
|
||||||
glVertex2d(cx, hy);
|
glVertex2d(cx, hy);
|
||||||
glVertex2d(cx, hym);
|
glVertex2d(cx, hym);
|
||||||
glEnd();
|
glEnd();
|
||||||
} else if(how == CLICK ||
|
} else if(how == CLICK ||
|
||||||
(how == HOVER && leftDown && editControl.colorPicker.picker1dActive))
|
(how == HOVER && leftDown && editControl.colorPicker.picker1dActive))
|
||||||
{
|
{
|
||||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||||
|
@ -765,7 +765,7 @@ bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
|
||||||
glVertex2d(cx, cy - 5);
|
glVertex2d(cx, cy - 5);
|
||||||
glVertex2d(cx, cy + 4);
|
glVertex2d(cx, cy + 4);
|
||||||
glEnd();
|
glEnd();
|
||||||
} else if(how == CLICK ||
|
} else if(how == CLICK ||
|
||||||
(how == HOVER && leftDown && editControl.colorPicker.picker2dActive))
|
(how == HOVER && leftDown && editControl.colorPicker.picker2dActive))
|
||||||
{
|
{
|
||||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||||
|
@ -783,7 +783,7 @@ bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
|
||||||
editControl.colorPicker.picker2dActive = true;
|
editControl.colorPicker.picker2dActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetMousePointerToHand(mousePointerAsHand);
|
SetMousePointerToHand(mousePointerAsHand);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +801,7 @@ void TextWindow::Paint(void) {
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glColor3d(1, 1, 1);
|
glColor3d(1, 1, 1);
|
||||||
|
|
||||||
glTranslated(-1, 1, 0);
|
glTranslated(-1, 1, 0);
|
||||||
glScaled(2.0/width, -2.0/height, 1);
|
glScaled(2.0/width, -2.0/height, 1);
|
||||||
// Make things round consistently, avoiding exact integer boundary
|
// Make things round consistently, avoiding exact integer boundary
|
||||||
|
|
|
@ -61,7 +61,7 @@ void GraphicsWindow::ToolbarDraw(void) {
|
||||||
bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
||||||
x += ((int)width/2);
|
x += ((int)width/2);
|
||||||
y += ((int)height/2);
|
y += ((int)height/2);
|
||||||
|
|
||||||
int nh = 0;
|
int nh = 0;
|
||||||
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
||||||
if(!withinToolbar) nh = 0;
|
if(!withinToolbar) nh = 0;
|
||||||
|
@ -88,7 +88,7 @@ bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
||||||
bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
|
bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
|
||||||
x += ((int)width/2);
|
x += ((int)width/2);
|
||||||
y += ((int)height/2);
|
y += ((int)height/2);
|
||||||
|
|
||||||
int nh = -1;
|
int nh = -1;
|
||||||
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
||||||
// They might have clicked within the toolbar, but not on a button.
|
// They might have clicked within the toolbar, but not on a button.
|
||||||
|
@ -120,7 +120,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
|
||||||
// This gets called every MouseMove event, so return quickly.
|
// This gets called every MouseMove event, so return quickly.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(paint) {
|
if(paint) {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -221,7 +221,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
|
||||||
|
|
||||||
int tw = (int)strlen(str)*SS.TW.CHAR_WIDTH + 10,
|
int tw = (int)strlen(str)*SS.TW.CHAR_WIDTH + 10,
|
||||||
th = SS.TW.LINE_HEIGHT + 2;
|
th = SS.TW.LINE_HEIGHT + 2;
|
||||||
|
|
||||||
double ox = toolbarMouseX + 3, oy = toolbarMouseY + 3;
|
double ox = toolbarMouseX + 3, oy = toolbarMouseY + 3;
|
||||||
glLineWidth(1);
|
glLineWidth(1);
|
||||||
glColor4d(1.0, 1.0, 0.6, 1.0);
|
glColor4d(1.0, 1.0, 0.6, 1.0);
|
||||||
|
|
16
src/ttf.cpp
16
src/ttf.cpp
|
@ -199,7 +199,7 @@ void TtfFont::LoadGlyph(int index) {
|
||||||
}
|
}
|
||||||
y[i] = ya;
|
y[i] = ya;
|
||||||
}
|
}
|
||||||
|
|
||||||
Glyph *g = &(glyph[index]);
|
Glyph *g = &(glyph[index]);
|
||||||
g->pt = (FontPoint *)MemAlloc(totalPts*sizeof(FontPoint));
|
g->pt = (FontPoint *)MemAlloc(totalPts*sizeof(FontPoint));
|
||||||
int contour = 0;
|
int contour = 0;
|
||||||
|
@ -245,7 +245,7 @@ bool TtfFont::LoadFontFromFile(bool nameOnly) {
|
||||||
if(loaded) return true;
|
if(loaded) return true;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fh = fopen(fontFile, "rb");
|
fh = fopen(fontFile, "rb");
|
||||||
if(!fh) {
|
if(!fh) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -358,7 +358,7 @@ bool TtfFont::LoadFontFromFile(bool nameOnly) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name.str[c++] = '\0';
|
name.str[c++] = '\0';
|
||||||
|
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ bool TtfFont::LoadFontFromFile(bool nameOnly) {
|
||||||
uint16_t headFontDirectionHint = GetUSHORT();
|
uint16_t headFontDirectionHint = GetUSHORT();
|
||||||
uint16_t headIndexToLocFormat = GetUSHORT();
|
uint16_t headIndexToLocFormat = GetUSHORT();
|
||||||
uint16_t headGlyphDataFormat = GetUSHORT();
|
uint16_t headGlyphDataFormat = GetUSHORT();
|
||||||
|
|
||||||
if(headMagicNumber != 0x5F0F3CF5) {
|
if(headMagicNumber != 0x5F0F3CF5) {
|
||||||
throw "bad magic number";
|
throw "bad magic number";
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ bool TtfFont::LoadFontFromFile(bool nameOnly) {
|
||||||
uint16_t mapSearchRange = GetUSHORT();
|
uint16_t mapSearchRange = GetUSHORT();
|
||||||
uint16_t mapEntrySelector = GetUSHORT();
|
uint16_t mapEntrySelector = GetUSHORT();
|
||||||
uint16_t mapRangeShift = GetUSHORT();
|
uint16_t mapRangeShift = GetUSHORT();
|
||||||
|
|
||||||
if(mapFormat != 4) {
|
if(mapFormat != 4) {
|
||||||
// Required to use format 4 per spec
|
// Required to use format 4 per spec
|
||||||
throw "not format 4";
|
throw "not format 4";
|
||||||
|
@ -606,7 +606,7 @@ void TtfFont::Handle(int *dx, int x, int y, bool onCurve) {
|
||||||
// but we must store the off-curve point.
|
// but we must store the off-curve point.
|
||||||
} else if(lastWas == OFF_CURVE && onCurve) {
|
} else if(lastWas == OFF_CURVE && onCurve) {
|
||||||
// We are ready to do a Bezier.
|
// We are ready to do a Bezier.
|
||||||
Bezier(lastOnCurve.x, lastOnCurve.y,
|
Bezier(lastOnCurve.x, lastOnCurve.y,
|
||||||
lastOffCurve.x, lastOffCurve.y,
|
lastOffCurve.x, lastOffCurve.y,
|
||||||
x, y);
|
x, y);
|
||||||
} else if(lastWas == OFF_CURVE && !onCurve) {
|
} else if(lastWas == OFF_CURVE && !onCurve) {
|
||||||
|
@ -616,7 +616,7 @@ void TtfFont::Handle(int *dx, int x, int y, bool onCurve) {
|
||||||
IntPoint fake;
|
IntPoint fake;
|
||||||
fake.x = (x + lastOffCurve.x) / 2;
|
fake.x = (x + lastOffCurve.x) / 2;
|
||||||
fake.y = (y + lastOffCurve.y) / 2;
|
fake.y = (y + lastOffCurve.y) / 2;
|
||||||
Bezier(lastOnCurve.x, lastOnCurve.y,
|
Bezier(lastOnCurve.x, lastOnCurve.y,
|
||||||
lastOffCurve.x, lastOffCurve.y,
|
lastOffCurve.x, lastOffCurve.y,
|
||||||
fake.x, fake.y);
|
fake.x, fake.y);
|
||||||
|
|
||||||
|
@ -659,7 +659,7 @@ void TtfFont::PlotCharacter(int *dx, int c, double spacing) {
|
||||||
int firstInContour = 0;
|
int firstInContour = 0;
|
||||||
for(i = 0; i < g->pts; i++) {
|
for(i = 0; i < g->pts; i++) {
|
||||||
Handle(dx, g->pt[i].x, g->pt[i].y, g->pt[i].onCurve);
|
Handle(dx, g->pt[i].x, g->pt[i].y, g->pt[i].onCurve);
|
||||||
|
|
||||||
if(g->pt[i].lastInContour) {
|
if(g->pt[i].lastInContour) {
|
||||||
int f = firstInContour;
|
int f = firstInContour;
|
||||||
Handle(dx, g->pt[f].x, g->pt[f].y, g->pt[f].onCurve);
|
Handle(dx, g->pt[f].x, g->pt[f].y, g->pt[f].onCurve);
|
||||||
|
|
10
src/ui.h
10
src/ui.h
|
@ -90,12 +90,12 @@ public:
|
||||||
uint8_t *HsvPattern1d(double h, double s);
|
uint8_t *HsvPattern1d(double h, double s);
|
||||||
void ColorPickerDone(void);
|
void ColorPickerDone(void);
|
||||||
bool DrawOrHitTestColorPicker(int how, bool leftDown, double x, double y);
|
bool DrawOrHitTestColorPicker(int how, bool leftDown, double x, double y);
|
||||||
|
|
||||||
void Init(void);
|
void Init(void);
|
||||||
void MakeColorTable(const Color *in, float *out);
|
void MakeColorTable(const Color *in, float *out);
|
||||||
void Printf(bool half, const char *fmt, ...);
|
void Printf(bool half, const char *fmt, ...);
|
||||||
void ClearScreen(void);
|
void ClearScreen(void);
|
||||||
|
|
||||||
void Show(void);
|
void Show(void);
|
||||||
|
|
||||||
// State for the screen that we are showing in the text window.
|
// State for the screen that we are showing in the text window.
|
||||||
|
@ -520,7 +520,7 @@ public:
|
||||||
hEntity circle;
|
hEntity circle;
|
||||||
hEntity normal;
|
hEntity normal;
|
||||||
hConstraint constraint;
|
hConstraint constraint;
|
||||||
|
|
||||||
const char *description;
|
const char *description;
|
||||||
} pending;
|
} pending;
|
||||||
void ClearPending(void);
|
void ClearPending(void);
|
||||||
|
@ -539,7 +539,7 @@ public:
|
||||||
Vector p0, p1;
|
Vector p0, p1;
|
||||||
Vector u, v;
|
Vector u, v;
|
||||||
double r, theta0, theta1, dtheta;
|
double r, theta0, theta1, dtheta;
|
||||||
|
|
||||||
void MakeFromEntity(hEntity he, bool reverse);
|
void MakeFromEntity(hEntity he, bool reverse);
|
||||||
Vector PointAt(double t);
|
Vector PointAt(double t);
|
||||||
Vector TangentAt(double t);
|
Vector TangentAt(double t);
|
||||||
|
@ -558,7 +558,7 @@ public:
|
||||||
void ReplacePointInConstraints(hEntity oldpt, hEntity newpt);
|
void ReplacePointInConstraints(hEntity oldpt, hEntity newpt);
|
||||||
void FixConstraintsForRequestBeingDeleted(hRequest hr);
|
void FixConstraintsForRequestBeingDeleted(hRequest hr);
|
||||||
void FixConstraintsForPointBeingDeleted(hEntity hpt);
|
void FixConstraintsForPointBeingDeleted(hEntity hpt);
|
||||||
|
|
||||||
// The current selection.
|
// The current selection.
|
||||||
class Selection {
|
class Selection {
|
||||||
public:
|
public:
|
||||||
|
|
14
src/util.cpp
14
src/util.cpp
|
@ -100,7 +100,7 @@ bool StringEndsIn(const char *str, const char *ending)
|
||||||
int i, ls = (int)strlen(str), le = (int)strlen(ending);
|
int i, ls = (int)strlen(str), le = (int)strlen(ending);
|
||||||
|
|
||||||
if(ls < le) return false;
|
if(ls < le) return false;
|
||||||
|
|
||||||
for(i = 0; i < le; i++) {
|
for(i = 0; i < le; i++) {
|
||||||
if(tolower(ending[le-i-1]) != tolower(str[ls-i-1])) {
|
if(tolower(ending[le-i-1]) != tolower(str[ls-i-1])) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -614,7 +614,7 @@ Vector Vector::ScaleOutOfCsys(Vector u, Vector v, Vector n) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Vector::InPerspective(Vector u, Vector v, Vector n,
|
Vector Vector::InPerspective(Vector u, Vector v, Vector n,
|
||||||
Vector origin, double cameraTan)
|
Vector origin, double cameraTan)
|
||||||
{
|
{
|
||||||
Vector r = this->Minus(origin);
|
Vector r = this->Minus(origin);
|
||||||
|
@ -755,7 +755,7 @@ Vector Vector::ClosestOrtho(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Vector::ClampWithin(double minv, double maxv) {
|
Vector Vector::ClampWithin(double minv, double maxv) {
|
||||||
Vector ret = *this;
|
Vector ret = *this;
|
||||||
|
|
||||||
if(ret.x < minv) ret.x = minv;
|
if(ret.x < minv) ret.x = minv;
|
||||||
|
@ -833,11 +833,11 @@ bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
||||||
Vector Vector::AtIntersectionOfPlanes(Vector n1, double d1,
|
Vector Vector::AtIntersectionOfPlanes(Vector n1, double d1,
|
||||||
Vector n2, double d2)
|
Vector n2, double d2)
|
||||||
{
|
{
|
||||||
double det = (n1.Dot(n1))*(n2.Dot(n2)) -
|
double det = (n1.Dot(n1))*(n2.Dot(n2)) -
|
||||||
(n1.Dot(n2))*(n1.Dot(n2));
|
(n1.Dot(n2))*(n1.Dot(n2));
|
||||||
double c1 = (d1*n2.Dot(n2) - d2*n1.Dot(n2))/det;
|
double c1 = (d1*n2.Dot(n2) - d2*n1.Dot(n2))/det;
|
||||||
double c2 = (d2*n1.Dot(n1) - d1*n1.Dot(n2))/det;
|
double c2 = (d2*n1.Dot(n1) - d1*n1.Dot(n2))/det;
|
||||||
|
|
||||||
return (n1.ScaledBy(c1)).Plus(n2.ScaledBy(c2));
|
return (n1.ScaledBy(c1)).Plus(n2.ScaledBy(c2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ void Vector::ClosestPointBetweenLines(Vector a0, Vector da,
|
||||||
// So dot this equation against dna and dnb to get two equations
|
// So dot this equation against dna and dnb to get two equations
|
||||||
// to solve for da and db
|
// to solve for da and db
|
||||||
*tb = ((a0.Minus(b0)).Dot(dna))/(db.Dot(dna));
|
*tb = ((a0.Minus(b0)).Dot(dna))/(db.Dot(dna));
|
||||||
*ta = -((a0.Minus(b0)).Dot(dnb))/(da.Dot(dnb));
|
*ta = -((a0.Minus(b0)).Dot(dnb))/(da.Dot(dnb));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Vector::AtIntersectionOfLines(Vector a0, Vector a1,
|
Vector Vector::AtIntersectionOfLines(Vector a0, Vector a1,
|
||||||
|
@ -1052,7 +1052,7 @@ double Point2d::Dot(Point2d p) {
|
||||||
double Point2d::DistanceToLine(Point2d p0, Point2d dp, bool segment) {
|
double Point2d::DistanceToLine(Point2d p0, Point2d dp, bool segment) {
|
||||||
double m = dp.x*dp.x + dp.y*dp.y;
|
double m = dp.x*dp.x + dp.y*dp.y;
|
||||||
if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE;
|
if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE;
|
||||||
|
|
||||||
// Let our line be p = p0 + t*dp, for a scalar t from 0 to 1
|
// Let our line be p = p0 + t*dp, for a scalar t from 0 to 1
|
||||||
double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m;
|
double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m;
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ void ThawWindowPosF(HWND hwnd, const char *subKey, const char *name)
|
||||||
if(v)
|
if(v)
|
||||||
ShowWindow(hwnd, SW_MAXIMIZE);
|
ShowWindow(hwnd, SW_MAXIMIZE);
|
||||||
|
|
||||||
|
|
||||||
HMONITOR hMonitor;
|
HMONITOR hMonitor;
|
||||||
MONITORINFO mi;
|
MONITORINFO mi;
|
||||||
RECT dr;
|
RECT dr;
|
||||||
|
@ -152,7 +152,7 @@ void FreezeDWORDF(DWORD val, const char *subKey, const char *name)
|
||||||
HKEY sub;
|
HKEY sub;
|
||||||
if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS)
|
if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(RegSetValueEx(sub, name, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD)) != ERROR_SUCCESS)
|
if(RegSetValueEx(sub, name, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD)) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ void FreezeStringF(const char *val, const char *subKey, const char *name)
|
||||||
HKEY sub;
|
HKEY sub;
|
||||||
if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS)
|
if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(RegSetValueEx(sub, name, 0, REG_SZ, (const BYTE *)val, (DWORD)strlen(val)+1) != ERROR_SUCCESS)
|
if(RegSetValueEx(sub, name, 0, REG_SZ, (const BYTE *)val, (DWORD)strlen(val)+1) != ERROR_SUCCESS)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ SiHdl SpaceNavigator = SI_NO_HANDLE;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Routines to display message boxes on screen. Do our own, instead of using
|
// Routines to display message boxes on screen. Do our own, instead of using
|
||||||
// MessageBox, because that is not consistent from version to version and
|
// MessageBox, because that is not consistent from version to version and
|
||||||
// there's word wrap problems.
|
// there's word wrap problems.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ static LRESULT CALLBACK MessageProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
row++;
|
row++;
|
||||||
} else {
|
} else {
|
||||||
TextOut(hdc, col*SS.TW.CHAR_WIDTH + 10,
|
TextOut(hdc, col*SS.TW.CHAR_WIDTH + 10,
|
||||||
row*SS.TW.LINE_HEIGHT + 10,
|
row*SS.TW.LINE_HEIGHT + 10,
|
||||||
&(MessageString[i]), 1);
|
&(MessageString[i]), 1);
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ HWND CreateWindowClient(DWORD exStyle, const char *className, const char *window
|
||||||
GetClientRect(h, &r);
|
GetClientRect(h, &r);
|
||||||
width = width - (r.right - width);
|
width = width - (r.right - width);
|
||||||
height = height - (r.bottom - height);
|
height = height - (r.bottom - height);
|
||||||
|
|
||||||
SetWindowPos(h, HWND_TOP, x, y, width, height, 0);
|
SetWindowPos(h, HWND_TOP, x, y, width, height, 0);
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
|
@ -161,7 +161,7 @@ void DoMessageBox(const char *str, int rows, int cols, bool error)
|
||||||
OkButton = CreateWindowEx(0, WC_BUTTON, "OK",
|
OkButton = CreateWindowEx(0, WC_BUTTON, "OK",
|
||||||
WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON,
|
WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON,
|
||||||
(width - 70)/2, rows*SS.TW.LINE_HEIGHT + 20,
|
(width - 70)/2, rows*SS.TW.LINE_HEIGHT + 20,
|
||||||
70, 25, MessageWnd, NULL, Instance, NULL);
|
70, 25, MessageWnd, NULL, Instance, NULL);
|
||||||
SendMessage(OkButton, WM_SETFONT, (WPARAM)FixedFont, true);
|
SendMessage(OkButton, WM_SETFONT, (WPARAM)FixedFont, true);
|
||||||
|
|
||||||
ShowWindow(MessageWnd, true);
|
ShowWindow(MessageWnd, true);
|
||||||
|
@ -184,7 +184,7 @@ void DoMessageBox(const char *str, int rows, int cols, bool error)
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageString = NULL;
|
MessageString = NULL;
|
||||||
EnableWindow(TextWnd, true);
|
EnableWindow(TextWnd, true);
|
||||||
EnableWindow(GraphicsWnd, true);
|
EnableWindow(GraphicsWnd, true);
|
||||||
|
@ -197,7 +197,7 @@ void AddContextMenuItem(const char *label, int id)
|
||||||
if(!ContextMenu) ContextMenu = CreatePopupMenu();
|
if(!ContextMenu) ContextMenu = CreatePopupMenu();
|
||||||
|
|
||||||
if(id == CONTEXT_SUBMENU) {
|
if(id == CONTEXT_SUBMENU) {
|
||||||
AppendMenu(ContextMenu, MF_STRING | MF_POPUP,
|
AppendMenu(ContextMenu, MF_STRING | MF_POPUP,
|
||||||
(UINT_PTR)ContextSubmenu, label);
|
(UINT_PTR)ContextSubmenu, label);
|
||||||
ContextSubmenu = NULL;
|
ContextSubmenu = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -219,7 +219,7 @@ int ShowContextMenu(void)
|
||||||
{
|
{
|
||||||
POINT p;
|
POINT p;
|
||||||
GetCursorPos(&p);
|
GetCursorPos(&p);
|
||||||
int r = TrackPopupMenu(ContextMenu,
|
int r = TrackPopupMenu(ContextMenu,
|
||||||
TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_TOPALIGN,
|
TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_TOPALIGN,
|
||||||
p.x, p.y, 0, GraphicsWnd, NULL);
|
p.x, p.y, 0, GraphicsWnd, NULL);
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ void HandleTextWindowScrollBar(WPARAM wParam, LPARAM lParam)
|
||||||
case SB_THUMBTRACK:
|
case SB_THUMBTRACK:
|
||||||
case SB_THUMBPOSITION: pos = HIWORD(wParam); break;
|
case SB_THUMBPOSITION: pos = HIWORD(wParam); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.TW.ScrollbarEvent(pos);
|
SS.TW.ScrollbarEvent(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ static void MouseWheel(int thisDelta) {
|
||||||
POINT pt;
|
POINT pt;
|
||||||
GetCursorPos(&pt);
|
GetCursorPos(&pt);
|
||||||
HWND hw = WindowFromPoint(pt);
|
HWND hw = WindowFromPoint(pt);
|
||||||
|
|
||||||
// Make the mousewheel work according to which window the mouse is
|
// Make the mousewheel work according to which window the mouse is
|
||||||
// over, not according to which window is active.
|
// over, not according to which window is active.
|
||||||
bool inTextWindow;
|
bool inTextWindow;
|
||||||
|
@ -419,7 +419,7 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
EndPaint(hwnd, &ps);
|
EndPaint(hwnd, &ps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_SIZING: {
|
case WM_SIZING: {
|
||||||
RECT *r = (RECT *)lParam;
|
RECT *r = (RECT *)lParam;
|
||||||
int hc = (r->bottom - r->top) - ClientIsSmallerBy;
|
int hc = (r->bottom - r->top) - ClientIsSmallerBy;
|
||||||
|
@ -477,7 +477,7 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
SS.TW.MouseEvent(msg == WM_LBUTTONDOWN, wParam & MK_LBUTTON, x, y);
|
SS.TW.MouseEvent(msg == WM_LBUTTONDOWN, wParam & MK_LBUTTON, x, y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_SIZE: {
|
case WM_SIZE: {
|
||||||
RECT r;
|
RECT r;
|
||||||
GetWindowRect(TextWndScrollBar, &r);
|
GetWindowRect(TextWndScrollBar, &r);
|
||||||
|
@ -618,23 +618,23 @@ static void CreateGlContext(HWND hwnd, HGLRC *glrc)
|
||||||
int pixelFormat;
|
int pixelFormat;
|
||||||
|
|
||||||
memset(&pfd, 0, sizeof(pfd));
|
memset(&pfd, 0, sizeof(pfd));
|
||||||
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||||
pfd.nVersion = 1;
|
pfd.nVersion = 1;
|
||||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
|
||||||
PFD_DOUBLEBUFFER;
|
PFD_DOUBLEBUFFER;
|
||||||
pfd.dwLayerMask = PFD_MAIN_PLANE;
|
pfd.dwLayerMask = PFD_MAIN_PLANE;
|
||||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||||
pfd.cColorBits = 32;
|
pfd.cColorBits = 32;
|
||||||
pfd.cDepthBits = 24;
|
pfd.cDepthBits = 24;
|
||||||
pfd.cAccumBits = 0;
|
pfd.cAccumBits = 0;
|
||||||
pfd.cStencilBits = 0;
|
pfd.cStencilBits = 0;
|
||||||
|
|
||||||
pixelFormat = ChoosePixelFormat(hdc, &pfd);
|
pixelFormat = ChoosePixelFormat(hdc, &pfd);
|
||||||
if(!pixelFormat) oops();
|
if(!pixelFormat) oops();
|
||||||
|
|
||||||
if(!SetPixelFormat(hdc, pixelFormat, &pfd)) oops();
|
if(!SetPixelFormat(hdc, pixelFormat, &pfd)) oops();
|
||||||
|
|
||||||
*glrc = wglCreateContext(hdc);
|
*glrc = wglCreateContext(hdc);
|
||||||
wglMakeCurrent(hdc, *glrc);
|
wglMakeCurrent(hdc, *glrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,7 +897,7 @@ int SaveFileYesNoCancel(void)
|
||||||
EnableWindow(GraphicsWnd, false);
|
EnableWindow(GraphicsWnd, false);
|
||||||
EnableWindow(TextWnd, false);
|
EnableWindow(TextWnd, false);
|
||||||
|
|
||||||
int r = MessageBox(GraphicsWnd,
|
int r = MessageBox(GraphicsWnd,
|
||||||
"The program has changed since it was last saved.\r\n\r\n"
|
"The program has changed since it was last saved.\r\n\r\n"
|
||||||
"Do you want to save the changes?", "SolveSpace",
|
"Do you want to save the changes?", "SolveSpace",
|
||||||
MB_YESNOCANCEL | MB_ICONWARNING);
|
MB_YESNOCANCEL | MB_ICONWARNING);
|
||||||
|
@ -948,7 +948,7 @@ static void MenuById(int id, bool yes, bool check)
|
||||||
|
|
||||||
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
|
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
if(SS.GW.menu[i].level == 0) subMenu++;
|
if(SS.GW.menu[i].level == 0) subMenu++;
|
||||||
|
|
||||||
if(SS.GW.menu[i].id == id) {
|
if(SS.GW.menu[i].id == id) {
|
||||||
if(subMenu < 0) oops();
|
if(subMenu < 0) oops();
|
||||||
if(subMenu >= (int)arraylen(SubMenus)) oops();
|
if(subMenu >= (int)arraylen(SubMenus)) oops();
|
||||||
|
@ -1005,7 +1005,7 @@ HMENU CreateGraphicsWindowMenus(void)
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int subMenu = 0;
|
int subMenu = 0;
|
||||||
|
|
||||||
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
|
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
char label[100] = { '\0' };
|
char label[100] = { '\0' };
|
||||||
if(SS.GW.menu[i].label) {
|
if(SS.GW.menu[i].label) {
|
||||||
|
@ -1054,7 +1054,7 @@ static void CreateMainWindows(void)
|
||||||
wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC |
|
wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_OWNDC |
|
||||||
CS_DBLCLKS;
|
CS_DBLCLKS;
|
||||||
wc.lpfnWndProc = (WNDPROC)GraphicsWndProc;
|
wc.lpfnWndProc = (WNDPROC)GraphicsWndProc;
|
||||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||||
wc.lpszClassName = "GraphicsWnd";
|
wc.lpszClassName = "GraphicsWnd";
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
@ -1088,13 +1088,13 @@ static void CreateMainWindows(void)
|
||||||
|
|
||||||
// We get the desired Alt+Tab behaviour by specifying that the text
|
// We get the desired Alt+Tab behaviour by specifying that the text
|
||||||
// window is a child of the graphics window.
|
// window is a child of the graphics window.
|
||||||
TextWnd = CreateWindowEx(0,
|
TextWnd = CreateWindowEx(0,
|
||||||
"TextWnd", "SolveSpace - Browser", WS_THICKFRAME | WS_CLIPCHILDREN,
|
"TextWnd", "SolveSpace - Browser", WS_THICKFRAME | WS_CLIPCHILDREN,
|
||||||
650, 500, 420, 300, GraphicsWnd, (HMENU)NULL, Instance, NULL);
|
650, 500, 420, 300, GraphicsWnd, (HMENU)NULL, Instance, NULL);
|
||||||
if(!TextWnd) oops();
|
if(!TextWnd) oops();
|
||||||
|
|
||||||
TextWndScrollBar = CreateWindowEx(0, WC_SCROLLBAR, "", WS_CHILD |
|
TextWndScrollBar = CreateWindowEx(0, WC_SCROLLBAR, "", WS_CHILD |
|
||||||
SBS_VERT | SBS_LEFTALIGN | WS_VISIBLE | WS_CLIPSIBLINGS,
|
SBS_VERT | SBS_LEFTALIGN | WS_VISIBLE | WS_CLIPSIBLINGS,
|
||||||
200, 100, 100, 100, TextWnd, NULL, Instance, NULL);
|
200, 100, 100, 100, TextWnd, NULL, Instance, NULL);
|
||||||
// Force the scrollbar to get resized to the window,
|
// Force the scrollbar to get resized to the window,
|
||||||
TextWndProc(TextWnd, WM_SIZE, 0, 0);
|
TextWndProc(TextWnd, WM_SIZE, 0, 0);
|
||||||
|
@ -1179,12 +1179,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
|
|
||||||
ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
|
ShowWindow(TextWnd, SW_SHOWNOACTIVATE);
|
||||||
ShowWindow(GraphicsWnd, SW_SHOW);
|
ShowWindow(GraphicsWnd, SW_SHOW);
|
||||||
|
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
SwapBuffers(GetDC(GraphicsWnd));
|
SwapBuffers(GetDC(GraphicsWnd));
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
SwapBuffers(GetDC(GraphicsWnd));
|
SwapBuffers(GetDC(GraphicsWnd));
|
||||||
|
|
||||||
// Create the heaps for all dynamic memory (AllocTemporary, MemAlloc)
|
// Create the heaps for all dynamic memory (AllocTemporary, MemAlloc)
|
||||||
|
@ -1217,7 +1217,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
SiSetUiMode(SpaceNavigator, SI_UI_NO_CONTROLS);
|
SiSetUiMode(SpaceNavigator, SI_UI_NO_CONTROLS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Call in to the platform-independent code, and let them do their init
|
// Call in to the platform-independent code, and let them do their init
|
||||||
SS.Init(file);
|
SS.Init(file);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue