A monster change; move the parameter, entity, group, and constraint

tables from SolveSpace to their own class. This is intended to
simplify use of the constraint solver in a library.

[git-p4: depot-paths = "//depot/solvespace/": change = 1942]
solver
Jonathan Westhues 2009-04-18 21:53:16 -08:00
parent b293c0ef41
commit a4dc518a89
23 changed files with 734 additions and 722 deletions

View File

@ -55,7 +55,7 @@ LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib opengl32.lib g
all: $(OBJDIR)/solvespace.exe
@cp $(OBJDIR)/solvespace.exe .
solvespace t7.slvs
solvespace alext.slvs
clean:
rm -f obj/*

View File

@ -49,16 +49,16 @@ char *Constraint::DescriptionString(void) {
//-----------------------------------------------------------------------------
void Constraint::DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA)
{
SS.constraint.ClearTags();
for(int i = 0; i < SS.constraint.n; i++) {
Constraint *ct = &(SS.constraint.elem[i]);
SK.constraint.ClearTags();
for(int i = 0; i < SK.constraint.n; i++) {
Constraint *ct = &(SK.constraint.elem[i]);
if(ct->type != type) continue;
if(ct->entityA.v != entityA.v) continue;
if(ct->ptA.v != ptA.v) continue;
ct->tag = 1;
}
SS.constraint.RemoveTagged();
SK.constraint.RemoveTagged();
// And no need to do anything special, since nothing
// ever depends on a constraint. But do clear the
// hover, in case the just-deleted constraint was
@ -72,7 +72,7 @@ void Constraint::AddConstraint(Constraint *c) {
void Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
if(rememberForUndo) SS.UndoRemember();
SS.constraint.AddAndAssignId(c);
SK.constraint.AddAndAssignId(c);
SS.MarkGroupDirty(c->group);
SS.later.generateAll = true;
@ -119,7 +119,7 @@ void Constraint::MenuConstrain(int id) {
c.ptB = gs.point[1];
} else if(gs.lineSegments == 1 && gs.n == 1) {
c.type = PT_PT_DISTANCE;
Entity *e = SS.GetEntity(gs.entity[0]);
Entity *e = SK.GetEntity(gs.entity[0]);
c.ptA = e->point[0];
c.ptB = e->point[1];
} else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) {
@ -150,8 +150,8 @@ void Constraint::MenuConstrain(int id) {
}
if(c.type == PT_PT_DISTANCE) {
Vector n = SS.GW.projRight.Cross(SS.GW.projUp);
Vector a = SS.GetEntity(c.ptA)->PointGetNum();
Vector b = SS.GetEntity(c.ptB)->PointGetNum();
Vector a = SK.GetEntity(c.ptA)->PointGetNum();
Vector b = SK.GetEntity(c.ptB)->PointGetNum();
c.disp.offset = n.Cross(a.Minus(b));
c.disp.offset = (c.disp.offset).WithMagnitude(50/SS.GW.scale);
} else {
@ -240,7 +240,7 @@ void Constraint::MenuConstrain(int id) {
c.entityB = gs.entity[1];
} else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) {
c.type = EQUAL_LINE_ARC_LEN;
if(SS.GetEntity(gs.entity[0])->type == Entity::ARC_OF_CIRCLE) {
if(SK.GetEntity(gs.entity[0])->type == Entity::ARC_OF_CIRCLE) {
c.entityA = gs.entity[1];
c.entityB = gs.entity[0];
} else {
@ -268,10 +268,10 @@ void Constraint::MenuConstrain(int id) {
}
if(c.type == EQUAL_ANGLE) {
// Infer the nearest supplementary angle from the sketch.
Vector a1 = SS.GetEntity(c.entityA)->VectorGetNum(),
b1 = SS.GetEntity(c.entityB)->VectorGetNum(),
a2 = SS.GetEntity(c.entityC)->VectorGetNum(),
b2 = SS.GetEntity(c.entityD)->VectorGetNum();
Vector a1 = SK.GetEntity(c.entityA)->VectorGetNum(),
b1 = SK.GetEntity(c.entityB)->VectorGetNum(),
a2 = SK.GetEntity(c.entityC)->VectorGetNum(),
b2 = SK.GetEntity(c.entityD)->VectorGetNum();
double d1 = a1.Dot(b1), d2 = a2.Dot(b2);
if(d1*d2 < 0) {
@ -309,7 +309,7 @@ void Constraint::MenuConstrain(int id) {
DeleteAllConstraintsFor(PT_ON_LINE, c.entityA, c.ptA);
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = AT_MIDPOINT;
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
c.entityA = gs.entity[i];
c.entityB = gs.entity[1-i];
} else {
@ -336,16 +336,16 @@ void Constraint::MenuConstrain(int id) {
((gs.workplanes == 1 && gs.n == 2) ||
(gs.n == 1)))
{
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
Entity *line = SS.GetEntity(gs.entity[i]);
int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
Entity *line = SK.GetEntity(gs.entity[i]);
c.entityA = gs.entity[1-i];
c.ptA = line->point[0];
c.ptB = line->point[1];
} else if(SS.GW.LockedInWorkplane()
&& gs.lineSegments == 2 && gs.n == 2)
{
Entity *l0 = SS.GetEntity(gs.entity[0]),
*l1 = SS.GetEntity(gs.entity[1]);
Entity *l0 = SK.GetEntity(gs.entity[0]),
*l1 = SK.GetEntity(gs.entity[1]);
if((l1->group.v != SS.GW.activeGroup.v) ||
(l1->construction && !(l0->construction)))
@ -384,10 +384,10 @@ void Constraint::MenuConstrain(int id) {
"symmetric without an explicit symmetry plane.");
return;
}
Vector pa = SS.GetEntity(c.ptA)->PointGetNum();
Vector pb = SS.GetEntity(c.ptB)->PointGetNum();
Vector pa = SK.GetEntity(c.ptA)->PointGetNum();
Vector pb = SK.GetEntity(c.ptB)->PointGetNum();
Vector dp = pa.Minus(pb);
Entity *norm = SS.GetEntity(c.workplane)->Normal();;
Entity *norm = SK.GetEntity(c.workplane)->Normal();;
Vector u = norm->NormalU(), v = norm->NormalV();
if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) {
c.type = SYMMETRIC_HORIZ;
@ -419,7 +419,7 @@ void Constraint::MenuConstrain(int id) {
}
if(gs.lineSegments == 1 && gs.n == 1) {
c.entityA = gs.entity[0];
Entity *e = SS.GetEntity(c.entityA);
Entity *e = SK.GetEntity(c.entityA);
ha = e->point[0];
hb = e->point[1];
} else if(gs.points == 2 && gs.n == 2) {
@ -454,8 +454,8 @@ void Constraint::MenuConstrain(int id) {
}
SS.UndoRemember();
Entity *nfree = SS.GetEntity(c.entityA);
Entity *nref = SS.GetEntity(c.entityB);
Entity *nfree = SK.GetEntity(c.entityA);
Entity *nref = SK.GetEntity(c.entityB);
if(nref->group.v == SS.GW.activeGroup.v) {
SWAP(Entity *, nref, nfree);
}
@ -485,7 +485,7 @@ void Constraint::MenuConstrain(int id) {
case GraphicsWindow::MNU_OTHER_ANGLE:
if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SS.GetConstraint(gs.constraint[0]);
Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->type == ANGLE) {
SS.UndoRemember();
c->other = !(c->other);
@ -505,10 +505,10 @@ void Constraint::MenuConstrain(int id) {
case GraphicsWindow::MNU_REFERENCE:
if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SS.GetConstraint(gs.constraint[0]);
Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->HasLabel() && c->type != COMMENT) {
(c->reference) = !(c->reference);
SS.GetGroup(c->group)->clean = false;
SK.GetGroup(c->group)->clean = false;
SS.GenerateAll();
break;
}
@ -531,15 +531,15 @@ void Constraint::MenuConstrain(int id) {
return;
}
Entity *ea = SS.GetEntity(c.entityA),
*eb = SS.GetEntity(c.entityB);
Entity *ea = SK.GetEntity(c.entityA),
*eb = SK.GetEntity(c.entityB);
if(ea->type == Entity::LINE_SEGMENT &&
eb->type == Entity::LINE_SEGMENT)
{
Vector a0 = SS.GetEntity(ea->point[0])->PointGetNum(),
a1 = SS.GetEntity(ea->point[1])->PointGetNum(),
b0 = SS.GetEntity(eb->point[0])->PointGetNum(),
b1 = SS.GetEntity(eb->point[1])->PointGetNum();
Vector a0 = SK.GetEntity(ea->point[0])->PointGetNum(),
a1 = SK.GetEntity(ea->point[1])->PointGetNum(),
b0 = SK.GetEntity(eb->point[0])->PointGetNum(),
b1 = SK.GetEntity(eb->point[1])->PointGetNum();
if(a0.Equals(b0) || a1.Equals(b1)) {
// okay, vectors should be drawn in same sense
} else if(a0.Equals(b1) || a1.Equals(b0)) {
@ -560,15 +560,15 @@ void Constraint::MenuConstrain(int id) {
c.entityA = gs.vector[0];
c.entityB = gs.vector[1];
} else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) {
Entity *line = SS.GetEntity(gs.entity[0]);
Entity *arc = SS.GetEntity(gs.entity[1]);
Entity *line = SK.GetEntity(gs.entity[0]);
Entity *arc = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::ARC_OF_CIRCLE) {
SWAP(Entity *, line, arc);
}
Vector l0 = SS.GetEntity(line->point[0])->PointGetNum(),
l1 = SS.GetEntity(line->point[1])->PointGetNum();
Vector a1 = SS.GetEntity(arc->point[1])->PointGetNum(),
a2 = SS.GetEntity(arc->point[2])->PointGetNum();
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(),
a2 = SK.GetEntity(arc->point[2])->PointGetNum();
if(l0.Equals(a1) || l1.Equals(a1)) {
c.other = false;
@ -584,15 +584,15 @@ void Constraint::MenuConstrain(int id) {
c.entityA = arc->h;
c.entityB = line->h;
} else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) {
Entity *line = SS.GetEntity(gs.entity[0]);
Entity *cubic = SS.GetEntity(gs.entity[1]);
Entity *line = SK.GetEntity(gs.entity[0]);
Entity *cubic = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::CUBIC) {
SWAP(Entity *, line, cubic);
}
Vector l0 = SS.GetEntity(line->point[0])->PointGetNum(),
l1 = SS.GetEntity(line->point[1])->PointGetNum();
Vector a0 = SS.GetEntity(cubic->point[0])->PointGetNum(),
a3 = SS.GetEntity(cubic->point[3])->PointGetNum();
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector a0 = SK.GetEntity(cubic->point[0])->PointGetNum(),
a3 = SK.GetEntity(cubic->point[3])->PointGetNum();
if(l0.Equals(a0) || l1.Equals(a0)) {
c.other = false;

View File

@ -33,11 +33,11 @@ Expr *ConstraintBase::VectorsParallel(int eq, ExprVector a, ExprVector b) {
Expr *ConstraintBase::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln)
{
Entity *ln = SS.GetEntity(hln);
Entity *a = SS.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]);
Entity *ln = SK.GetEntity(hln);
Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SK.GetEntity(ln->point[1]);
Entity *p = SS.GetEntity(hpt);
Entity *p = SK.GetEntity(hpt);
if(wrkpl.v == Entity::FREE_IN_3D.v) {
ExprVector ep = p->PointGetExprs();
@ -71,13 +71,13 @@ Expr *ConstraintBase::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln)
Expr *ConstraintBase::PointPlaneDistance(ExprVector p, hEntity hpl) {
ExprVector n;
Expr *d;
SS.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d);
SK.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d);
return (p.Dot(n))->Minus(d);
}
Expr *ConstraintBase::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) {
Entity *pa = SS.GetEntity(hpa);
Entity *pb = SS.GetEntity(hpb);
Entity *pa = SK.GetEntity(hpa);
Entity *pb = SK.GetEntity(hpb);
if(!(pa->IsPoint() && pb->IsPoint())) oops();
if(wrkpl.v == Entity::FREE_IN_3D.v) {
@ -113,7 +113,7 @@ Expr *ConstraintBase::DirectionCosine(hEntity wrkpl,
Expr *mags = (ae.Magnitude())->Times(be.Magnitude());
return (ae.Dot(be))->Div(mags);
} else {
Entity *w = SS.GetEntity(wrkpl);
Entity *w = SK.GetEntity(wrkpl);
ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV();
Expr *ua = u.Dot(ae);
@ -130,7 +130,7 @@ Expr *ConstraintBase::DirectionCosine(hEntity wrkpl,
ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane,
Expr *u, Expr *v)
{
Entity *w = SS.GetEntity(workplane);
Entity *w = SK.GetEntity(workplane);
ExprVector ub = w->Normal()->NormalExprsU();
ExprVector vb = w->Normal()->NormalExprsV();
@ -141,8 +141,8 @@ ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane,
void ConstraintBase::ModifyToSatisfy(void) {
if(type == ANGLE) {
Vector a = SS.GetEntity(entityA)->VectorGetNum();
Vector b = SS.GetEntity(entityB)->VectorGetNum();
Vector a = SK.GetEntity(entityA)->VectorGetNum();
Vector b = SK.GetEntity(entityB)->VectorGetNum();
if(other) a = a.ScaledBy(-1);
if(workplane.v != Entity::FREE_IN_3D.v) {
a = a.ProjectVectorInto(workplane);
@ -195,14 +195,14 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
break;
case PT_PLANE_DISTANCE: {
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs();
ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0);
break;
}
case PT_FACE_DISTANCE: {
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs();
Entity *f = SS.GetEntity(entityA);
ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
Entity *f = SK.GetEntity(entityA);
ExprVector p0 = f->FaceGetPointExprs();
ExprVector n = f->FaceGetNormalExprs();
AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exA), 0);
@ -210,8 +210,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case EQUAL_LENGTH_LINES: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus(
Distance(workplane, b->point[0], b->point[1])), 0);
break;
@ -220,7 +220,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
// These work on distance squared, since the pt-line distances are
// signed, and we want the absolute value.
case EQ_LEN_PT_LINE_D: {
Entity *forLen = SS.GetEntity(entityA);
Entity *forLen = SK.GetEntity(entityA);
Expr *d1 = Distance(workplane, forLen->point[0], forLen->point[1]);
Expr *d2 = PointLineDistance(workplane, ptA, entityB);
AddEq(l, (d1->Square())->Minus(d2->Square()), 0);
@ -234,8 +234,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case LENGTH_RATIO: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
Expr *la = Distance(workplane, a->point[0], a->point[1]);
Expr *lb = Distance(workplane, b->point[0], b->point[1]);
AddEq(l, (la->Div(lb))->Minus(exA), 0);
@ -243,33 +243,33 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case DIAMETER: {
Entity *circle = SS.GetEntity(entityA);
Entity *circle = SK.GetEntity(entityA);
Expr *r = circle->CircleGetRadiusExpr();
AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0);
break;
}
case EQUAL_RADIUS: {
Entity *c1 = SS.GetEntity(entityA);
Entity *c2 = SS.GetEntity(entityB);
Entity *c1 = SK.GetEntity(entityA);
Entity *c2 = SK.GetEntity(entityB);
AddEq(l, (c1->CircleGetRadiusExpr())->Minus(
c2->CircleGetRadiusExpr()), 0);
break;
}
case EQUAL_LINE_ARC_LEN: {
Entity *line = SS.GetEntity(entityA),
*arc = SS.GetEntity(entityB);
Entity *line = SK.GetEntity(entityA),
*arc = SK.GetEntity(entityB);
// Get the line length
ExprVector l0 = SS.GetEntity(line->point[0])->PointGetExprs(),
l1 = SS.GetEntity(line->point[1])->PointGetExprs();
ExprVector l0 = SK.GetEntity(line->point[0])->PointGetExprs(),
l1 = SK.GetEntity(line->point[1])->PointGetExprs();
Expr *ll = (l1.Minus(l0)).Magnitude();
// And get the arc radius, and the cosine of its angle
Entity *ao = SS.GetEntity(arc->point[0]),
*as = SS.GetEntity(arc->point[1]),
*af = SS.GetEntity(arc->point[2]);
Entity *ao = SK.GetEntity(arc->point[0]),
*as = SK.GetEntity(arc->point[1]),
*af = SK.GetEntity(arc->point[2]);
ExprVector aos = (as->PointGetExprs()).Minus(ao->PointGetExprs()),
aof = (af->PointGetExprs()).Minus(ao->PointGetExprs());
@ -301,8 +301,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case POINTS_COINCIDENT: {
Entity *a = SS.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB);
Entity *a = SK.GetEntity(ptA);
Entity *b = SK.GetEntity(ptB);
if(workplane.v == Entity::FREE_IN_3D.v) {
ExprVector pa = a->PointGetExprs();
ExprVector pb = b->PointGetExprs();
@ -323,13 +323,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_IN_PLANE:
// This one works the same, whether projected or not.
AddEq(l, PointPlaneDistance(
SS.GetEntity(ptA)->PointGetExprs(), entityA), 0);
SK.GetEntity(ptA)->PointGetExprs(), entityA), 0);
break;
case PT_ON_FACE: {
// a plane, n dot (p - p0) = 0
ExprVector p = SS.GetEntity(ptA)->PointGetExprs();
Entity *f = SS.GetEntity(entityA);
ExprVector p = SK.GetEntity(ptA)->PointGetExprs();
Entity *f = SK.GetEntity(entityA);
ExprVector p0 = f->FaceGetPointExprs();
ExprVector n = f->FaceGetNormalExprs();
AddEq(l, (p.Minus(p0)).Dot(n), 0);
@ -338,10 +338,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_ON_LINE:
if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *ln = SS.GetEntity(entityA);
Entity *a = SS.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]);
Entity *p = SS.GetEntity(ptA);
Entity *ln = SK.GetEntity(entityA);
Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SK.GetEntity(ln->point[1]);
Entity *p = SK.GetEntity(ptA);
ExprVector ep = p->PointGetExprs();
ExprVector ea = a->PointGetExprs();
@ -370,10 +370,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_ON_CIRCLE: {
// This actually constrains the point to lie on the cylinder.
Entity *circle = SS.GetEntity(entityA);
ExprVector center = SS.GetEntity(circle->point[0])->PointGetExprs();
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs();
Entity *normal = SS.GetEntity(circle->normal);
Entity *circle = SK.GetEntity(entityA);
ExprVector center = SK.GetEntity(circle->point[0])->PointGetExprs();
ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
Entity *normal = SK.GetEntity(circle->normal);
ExprVector u = normal->NormalExprsU(),
v = normal->NormalExprsV();
@ -389,13 +389,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case AT_MIDPOINT:
if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *ln = SS.GetEntity(entityA);
ExprVector a = SS.GetEntity(ln->point[0])->PointGetExprs();
ExprVector b = SS.GetEntity(ln->point[1])->PointGetExprs();
Entity *ln = SK.GetEntity(entityA);
ExprVector a = SK.GetEntity(ln->point[0])->PointGetExprs();
ExprVector b = SK.GetEntity(ln->point[1])->PointGetExprs();
ExprVector m = (a.Plus(b)).ScaledBy(Expr::From(0.5));
if(ptA.v) {
ExprVector p = SS.GetEntity(ptA)->PointGetExprs();
ExprVector p = SK.GetEntity(ptA)->PointGetExprs();
AddEq(l, (m.x)->Minus(p.x), 0);
AddEq(l, (m.y)->Minus(p.y), 1);
AddEq(l, (m.z)->Minus(p.z), 2);
@ -403,9 +403,9 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, PointPlaneDistance(m, entityB), 0);
}
} else {
Entity *ln = SS.GetEntity(entityA);
Entity *a = SS.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]);
Entity *ln = SK.GetEntity(entityA);
Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SK.GetEntity(ln->point[1]);
Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -414,7 +414,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
Expr *mv = Expr::From(0.5)->Times(av->Plus(bv));
if(ptA.v) {
Entity *p = SS.GetEntity(ptA);
Entity *p = SK.GetEntity(ptA);
Expr *pu, *pv;
p->PointGetExprsInWorkplane(workplane, &pu, &pv);
AddEq(l, pu->Minus(mu), 0);
@ -428,9 +428,9 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case SYMMETRIC:
if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *plane = SS.GetEntity(entityA);
Entity *ea = SS.GetEntity(ptA);
Entity *eb = SS.GetEntity(ptB);
Entity *plane = SK.GetEntity(entityA);
Entity *ea = SK.GetEntity(ptA);
Entity *eb = SK.GetEntity(ptB);
ExprVector a = ea->PointGetExprs();
ExprVector b = eb->PointGetExprs();
@ -447,9 +447,9 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, au->Minus(bu), 1);
AddEq(l, av->Minus(bv), 2);
} else {
Entity *plane = SS.GetEntity(entityA);
Entity *a = SS.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB);
Entity *plane = SK.GetEntity(entityA);
Entity *a = SK.GetEntity(ptA);
Entity *b = SK.GetEntity(ptB);
Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -464,7 +464,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
// to the symmetry pane's normal (i.e., that lies in the
// plane of symmetry). The line connecting the points is
// perpendicular to that constructed vector.
Entity *w = SS.GetEntity(workplane);
Entity *w = SK.GetEntity(workplane);
ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV();
@ -479,8 +479,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case SYMMETRIC_HORIZ:
case SYMMETRIC_VERT: {
Entity *a = SS.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB);
Entity *a = SK.GetEntity(ptA);
Entity *b = SK.GetEntity(ptB);
Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -497,16 +497,16 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case SYMMETRIC_LINE: {
Entity *pa = SS.GetEntity(ptA);
Entity *pb = SS.GetEntity(ptB);
Entity *pa = SK.GetEntity(ptA);
Entity *pb = SK.GetEntity(ptB);
Expr *pau, *pav, *pbu, *pbv;
pa->PointGetExprsInWorkplane(workplane, &pau, &pav);
pb->PointGetExprsInWorkplane(workplane, &pbu, &pbv);
Entity *ln = SS.GetEntity(entityA);
Entity *la = SS.GetEntity(ln->point[0]);
Entity *lb = SS.GetEntity(ln->point[1]);
Entity *ln = SK.GetEntity(entityA);
Entity *la = SK.GetEntity(ln->point[0]);
Entity *lb = SK.GetEntity(ln->point[1]);
Expr *lau, *lav, *lbu, *lbv;
la->PointGetExprsInWorkplane(workplane, &lau, &lav);
lb->PointGetExprsInWorkplane(workplane, &lbu, &lbv);
@ -533,15 +533,15 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case VERTICAL: {
hEntity ha, hb;
if(entityA.v) {
Entity *e = SS.GetEntity(entityA);
Entity *e = SK.GetEntity(entityA);
ha = e->point[0];
hb = e->point[1];
} else {
ha = ptA;
hb = ptB;
}
Entity *a = SS.GetEntity(ha);
Entity *b = SS.GetEntity(hb);
Entity *a = SK.GetEntity(ha);
Entity *b = SK.GetEntity(hb);
Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -552,8 +552,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case SAME_ORIENTATION: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
if(b->group.v != group.v) {
SWAP(Entity *, a, b);
}
@ -581,8 +581,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PERPENDICULAR:
case ANGLE: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
ExprVector ae = a->VectorGetExprs();
ExprVector be = b->VectorGetExprs();
if(other) ae = ae.ScaledBy(Expr::From(-1));
@ -602,10 +602,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case EQUAL_ANGLE: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *c = SS.GetEntity(entityC);
Entity *d = SS.GetEntity(entityD);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
Entity *c = SK.GetEntity(entityC);
Entity *d = SK.GetEntity(entityD);
ExprVector ae = a->VectorGetExprs();
ExprVector be = b->VectorGetExprs();
ExprVector ce = c->VectorGetExprs();
@ -621,12 +621,12 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case ARC_LINE_TANGENT: {
Entity *arc = SS.GetEntity(entityA);
Entity *line = SS.GetEntity(entityB);
Entity *arc = SK.GetEntity(entityA);
Entity *line = SK.GetEntity(entityB);
ExprVector ac = SS.GetEntity(arc->point[0])->PointGetExprs();
ExprVector ac = SK.GetEntity(arc->point[0])->PointGetExprs();
ExprVector ap =
SS.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs();
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs();
ExprVector ld = line->VectorGetExprs();
@ -636,13 +636,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case CUBIC_LINE_TANGENT: {
Entity *cubic = SS.GetEntity(entityA);
Entity *line = SS.GetEntity(entityB);
Entity *cubic = SK.GetEntity(entityA);
Entity *line = SK.GetEntity(entityB);
ExprVector endpoint =
SS.GetEntity(cubic->point[other ? 3 : 0])->PointGetExprs();
SK.GetEntity(cubic->point[other ? 3 : 0])->PointGetExprs();
ExprVector ctrlpoint =
SS.GetEntity(cubic->point[other ? 2 : 1])->PointGetExprs();
SK.GetEntity(cubic->point[other ? 2 : 1])->PointGetExprs();
ExprVector a = endpoint.Minus(ctrlpoint);
@ -652,7 +652,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, VectorsParallel(0, a, b), 0);
AddEq(l, VectorsParallel(1, a, b), 1);
} else {
Entity *w = SS.GetEntity(workplane);
Entity *w = SK.GetEntity(workplane);
ExprVector wn = w->Normal()->NormalExprsN();
AddEq(l, (a.Cross(b)).Dot(wn), 0);
}
@ -660,7 +660,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
}
case PARALLEL: {
Entity *ea = SS.GetEntity(entityA), *eb = SS.GetEntity(entityB);
Entity *ea = SK.GetEntity(entityA), *eb = SK.GetEntity(entityB);
if(eb->group.v != group.v) {
SWAP(Entity *, ea, eb);
}
@ -671,7 +671,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, VectorsParallel(0, a, b), 0);
AddEq(l, VectorsParallel(1, a, b), 1);
} else {
Entity *w = SS.GetEntity(workplane);
Entity *w = SK.GetEntity(workplane);
ExprVector wn = w->Normal()->NormalExprsN();
AddEq(l, (a.Cross(b)).Dot(wn), 0);
}

120
draw.cpp
View File

@ -1,7 +1,7 @@
#include "solvespace.h"
void GraphicsWindow::UpdateDraggedPoint(hEntity hp, double mx, double my) {
Entity *p = SS.GetEntity(hp);
Entity *p = SK.GetEntity(hp);
Vector pos = p->PointGetNum();
UpdateDraggedNum(&pos, mx, my);
p->PointForceTo(pos);
@ -80,7 +80,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// start dragging something.
if(leftDown && dm > 3) {
if(hover.entity.v) {
Entity *e = SS.GetEntity(hover.entity);
Entity *e = SK.GetEntity(hover.entity);
if(e->IsPoint()) {
// Start dragging this point.
ClearSelection();
@ -97,7 +97,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
pending.operation = DRAGGING_NORMAL;
}
} else if(hover.constraint.v &&
SS.GetConstraint(hover.constraint)->HasLabel())
SK.GetConstraint(hover.constraint)->HasLabel())
{
ClearSelection();
pending.constraint = hover.constraint;
@ -132,7 +132,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
if(!havePainted) return;
switch(pending.operation) {
case DRAGGING_CONSTRAINT: {
Constraint *c = SS.constraint.FindById(pending.constraint);
Constraint *c = SK.constraint.FindById(pending.constraint);
UpdateDraggedNum(&(c->disp.offset), x, y);
break;
}
@ -141,7 +141,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// and fall through
case DRAGGING_NEW_POINT:
case DRAGGING_POINT: {
Entity *p = SS.GetEntity(pending.point);
Entity *p = SK.GetEntity(pending.point);
if((p->type == Entity::POINT_N_ROT_TRANS) &&
(shiftDown || ctrlDown))
{
@ -194,12 +194,12 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
HitTestMakeSelection(mp);
hRequest hr = pending.point.request();
Vector p0 = SS.GetEntity(hr.entity(1))->PointGetNum();
Vector p3 = SS.GetEntity(hr.entity(4))->PointGetNum();
Vector p0 = SK.GetEntity(hr.entity(1))->PointGetNum();
Vector p3 = SK.GetEntity(hr.entity(4))->PointGetNum();
Vector p1 = p0.ScaledBy(2.0/3).Plus(p3.ScaledBy(1.0/3));
SS.GetEntity(hr.entity(2))->PointForceTo(p1);
SK.GetEntity(hr.entity(2))->PointForceTo(p1);
Vector p2 = p0.ScaledBy(1.0/3).Plus(p3.ScaledBy(2.0/3));
SS.GetEntity(hr.entity(3))->PointForceTo(p2);
SK.GetEntity(hr.entity(3))->PointForceTo(p2);
SS.MarkGroupDirtyByEntity(pending.point);
break;
@ -209,30 +209,30 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
HitTestMakeSelection(mp);
hRequest hr = pending.point.request();
Vector ona = SS.GetEntity(hr.entity(2))->PointGetNum();
Vector onb = SS.GetEntity(hr.entity(3))->PointGetNum();
Vector ona = SK.GetEntity(hr.entity(2))->PointGetNum();
Vector onb = SK.GetEntity(hr.entity(3))->PointGetNum();
Vector center = (ona.Plus(onb)).ScaledBy(0.5);
SS.GetEntity(hr.entity(1))->PointForceTo(center);
SK.GetEntity(hr.entity(1))->PointForceTo(center);
SS.MarkGroupDirtyByEntity(pending.point);
break;
}
case DRAGGING_NEW_RADIUS:
case DRAGGING_RADIUS: {
Entity *circle = SS.GetEntity(pending.circle);
Vector center = SS.GetEntity(circle->point[0])->PointGetNum();
Entity *circle = SK.GetEntity(pending.circle);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Point2d c2 = ProjectPoint(center);
double r = c2.DistanceTo(mp)/scale;
SS.GetEntity(circle->distance)->DistanceForceTo(r);
SK.GetEntity(circle->distance)->DistanceForceTo(r);
SS.MarkGroupDirtyByEntity(pending.circle);
break;
}
case DRAGGING_NORMAL: {
Entity *normal = SS.GetEntity(pending.normal);
Vector p = SS.GetEntity(normal->point[0])->PointGetNum();
Entity *normal = SK.GetEntity(pending.normal);
Vector p = SK.GetEntity(normal->point[0])->PointGetNum();
Point2d p2 = ProjectPoint(p);
Quaternion q = normal->NormalGetNum();
@ -299,7 +299,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
Request r;
memset(&r, 0, sizeof(r));
r.group = activeGroup;
Group *g = SS.GetGroup(activeGroup);
Group *g = SK.GetGroup(activeGroup);
if(g->type == Group::DRAWING_3D || g->type == Group::DRAWING_WORKPLANE) {
r.construction = false;
} else {
@ -307,7 +307,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
}
r.workplane = ActiveWorkplane();
r.type = type;
SS.request.AddAndAssignId(&r);
SK.request.AddAndAssignId(&r);
// We must regenerate the parameters, so that the code that tries to
// place this request's entities where the mouse is can do so. But
@ -321,7 +321,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
bool GraphicsWindow::ConstrainPointByHovered(hEntity pt) {
if(!hover.entity.v) return false;
Entity *e = SS.GetEntity(hover.entity);
Entity *e = SK.GetEntity(hover.entity);
if(e->IsPoint()) {
Constraint::ConstrainCoincident(e->h, pt);
return true;
@ -362,7 +362,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
switch(pending.operation) {
case MNU_DATUM_POINT:
hr = AddRequest(Request::DATUM_POINT);
SS.GetEntity(hr.entity(0))->PointForceTo(v);
SK.GetEntity(hr.entity(0))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(0));
ClearSuper();
@ -372,7 +372,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
case MNU_LINE_SEGMENT:
hr = AddRequest(Request::LINE_SEGMENT);
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(1))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(1));
ClearSuper();
@ -380,7 +380,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.operation = DRAGGING_NEW_LINE_POINT;
pending.point = hr.entity(2);
pending.description = "click to place next point of line";
SS.GetEntity(pending.point)->PointForceTo(v);
SK.GetEntity(pending.point)->PointForceTo(v);
break;
case MNU_RECTANGLE: {
@ -398,8 +398,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
for(i = 0; i < 4; i++) {
Constraint::ConstrainCoincident(
lns[i].entity(1), lns[(i+1)%4].entity(2));
SS.GetEntity(lns[i].entity(1))->PointForceTo(v);
SS.GetEntity(lns[i].entity(2))->PointForceTo(v);
SK.GetEntity(lns[i].entity(1))->PointForceTo(v);
SK.GetEntity(lns[i].entity(2))->PointForceTo(v);
}
for(i = 0; i < 4; i++) {
Constraint::Constrain(
@ -416,8 +416,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
case MNU_CIRCLE:
hr = AddRequest(Request::CIRCLE);
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(32))->NormalForceTo(
SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(32))->NormalForceTo(
Quaternion::From(SS.GW.projRight, SS.GW.projUp));
ConstrainPointByHovered(hr.entity(1));
@ -426,7 +426,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.operation = DRAGGING_NEW_RADIUS;
pending.circle = hr.entity(0);
pending.description = "click to set radius";
SS.GetParam(hr.param(0))->val = 0;
SK.GetParam(hr.param(0))->val = 0;
break;
case MNU_ARC: {
@ -439,9 +439,9 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
// This fudge factor stops us from immediately failing to solve
// because of the arc's implicit (equal radius) tangent.
Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale);
SS.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj));
SS.GetEntity(hr.entity(2))->PointForceTo(v);
SS.GetEntity(hr.entity(3))->PointForceTo(v);
SK.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj));
SK.GetEntity(hr.entity(2))->PointForceTo(v);
SK.GetEntity(hr.entity(3))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(2));
ClearSuper();
@ -453,10 +453,10 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
case MNU_CUBIC:
hr = AddRequest(Request::CUBIC);
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v);
SS.GetEntity(hr.entity(3))->PointForceTo(v);
SS.GetEntity(hr.entity(4))->PointForceTo(v);
SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(2))->PointForceTo(v);
SK.GetEntity(hr.entity(3))->PointForceTo(v);
SK.GetEntity(hr.entity(4))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(1));
ClearSuper();
@ -474,8 +474,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break;
}
hr = AddRequest(Request::WORKPLANE);
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(32))->NormalForceTo(
SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(32))->NormalForceTo(
Quaternion::From(SS.GW.projRight, SS.GW.projUp));
ConstrainPointByHovered(hr.entity(1));
@ -489,12 +489,12 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break;
}
hr = AddRequest(Request::TTF_TEXT);
Request *r = SS.GetRequest(hr);
Request *r = SK.GetRequest(hr);
r->str.strcpy("Abc");
r->font.strcpy("arial.ttf");
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v);
SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(2))->PointForceTo(v);
pending.operation = DRAGGING_NEW_POINT;
pending.point = hr.entity(2);
@ -521,8 +521,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
// Create a new line segment, so that we continue drawing.
hRequest hr = AddRequest(Request::LINE_SEGMENT);
SS.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v);
SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(2))->PointForceTo(v);
// Constrain the line segments to share an endpoint
Constraint::ConstrainCoincident(pending.point, hr.entity(1));
@ -552,13 +552,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
}
if(i != MAX_SELECTED) break;
if(hover.entity.v != 0 && SS.GetEntity(hover.entity)->IsFace()) {
if(hover.entity.v != 0 && SK.GetEntity(hover.entity)->IsFace()) {
// In the interest of speed for the triangle drawing code,
// only two faces may be selected at a time.
int c = 0;
for(i = 0; i < MAX_SELECTED; i++) {
hEntity he = selection[i].entity;
if(he.v != 0 && SS.GetEntity(he)->IsFace()) {
if(he.v != 0 && SK.GetEntity(he)->IsFace()) {
c++;
if(c >= 2) selection[i].Clear();
}
@ -601,7 +601,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
constraintBeingEdited = hover.constraint;
ClearSuper();
Constraint *c = SS.GetConstraint(constraintBeingEdited);
Constraint *c = SK.GetConstraint(constraintBeingEdited);
if(c->reference) {
// Not meaningful to edit a reference dimension
return;
@ -631,7 +631,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
void GraphicsWindow::EditControlDone(char *s) {
HideGraphicsEditControl();
Constraint *c = SS.GetConstraint(constraintBeingEdited);
Constraint *c = SK.GetConstraint(constraintBeingEdited);
if(c->type == Constraint::COMMENT) {
SS.UndoRemember();
@ -728,13 +728,13 @@ void GraphicsWindow::Selection::Draw(void) {
Vector refp;
if(entity.v) {
glLineWidth(1.5);
Entity *e = SS.GetEntity(entity);
Entity *e = SK.GetEntity(entity);
e->Draw();
if(emphasized) refp = e->GetReferencePos();
glLineWidth(1);
}
if(constraint.v) {
Constraint *c = SS.GetConstraint(constraint);
Constraint *c = SK.GetConstraint(constraint);
c->Draw();
if(emphasized) refp = c->GetReferencePos();
}
@ -766,11 +766,11 @@ void GraphicsWindow::ClearNonexistentSelectionItems(void) {
bool change = false;
for(int i = 0; i < MAX_SELECTED; i++) {
Selection *s = &(selection[i]);
if(s->constraint.v && !(SS.constraint.FindByIdNoOops(s->constraint))) {
if(s->constraint.v && !(SK.constraint.FindByIdNoOops(s->constraint))) {
s->constraint.v = 0;
change = true;
}
if(s->entity.v && !(SS.entity.FindByIdNoOops(s->entity))) {
if(s->entity.v && !(SK.entity.FindByIdNoOops(s->entity))) {
s->entity.v = 0;
change = true;
}
@ -786,7 +786,7 @@ void GraphicsWindow::GroupSelection(void) {
if(s->entity.v) {
(gs.n)++;
Entity *e = SS.entity.FindById(s->entity);
Entity *e = SK.entity.FindById(s->entity);
// A list of points, and a list of all entities that aren't points.
if(e->IsPoint()) {
gs.point[(gs.points)++] = s->entity;
@ -841,8 +841,8 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
// Always do the entities; we might be dragging something that should
// be auto-constrained, and we need the hover for that.
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
// Don't hover whatever's being dragged.
if(e->h.request().v == pending.point.request().v) continue;
@ -857,18 +857,18 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
// The constraints and faces happen only when nothing's in progress.
if(pending.operation == 0) {
// Constraints
for(i = 0; i < SS.constraint.n; i++) {
d = SS.constraint.elem[i].GetDistance(mp);
for(i = 0; i < SK.constraint.n; i++) {
d = SK.constraint.elem[i].GetDistance(mp);
if(d < 10 && d < dmin) {
memset(&s, 0, sizeof(s));
s.constraint = SS.constraint.elem[i].h;
s.constraint = SK.constraint.elem[i].h;
dmin = d;
}
}
// Faces, from the triangle mesh; these are lowest priority
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) {
SMesh *m = &((SS.GetGroup(activeGroup))->runningMesh);
SMesh *m = &((SK.GetGroup(activeGroup))->runningMesh);
DWORD v = m->FirstIntersectionWith(mp);
if(v) {
s.entity.v = v;
@ -1001,7 +1001,7 @@ void GraphicsWindow::Paint(int w, int h) {
// Draw the active group; this fills the polygons in a drawing group, and
// draws the solid mesh.
(SS.GetGroup(activeGroup))->Draw();
(SK.GetGroup(activeGroup))->Draw();
// Now draw the entities
if(showHdnLines) glDisable(GL_DEPTH_TEST);
@ -1009,8 +1009,8 @@ void GraphicsWindow::Paint(int w, int h) {
glDisable(GL_DEPTH_TEST);
// Draw the constraints
for(i = 0; i < SS.constraint.n; i++) {
SS.constraint.elem[i].Draw();
for(i = 0; i < SK.constraint.n; i++) {
SK.constraint.elem[i].Draw();
}
// Draw the traced path, if one exists

View File

@ -105,9 +105,9 @@ void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn) {
}
void Constraint::DoEqualRadiusTicks(hEntity he) {
Entity *circ = SS.GetEntity(he);
Entity *circ = SK.GetEntity(he);
Vector center = SS.GetEntity(circ->point[0])->PointGetNum();
Vector center = SK.GetEntity(circ->point[0])->PointGetNum();
double r = circ->CircleGetRadiusNum();
Quaternion q = circ->Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV();
@ -194,7 +194,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
void Constraint::DrawOrGetDistance(Vector *labelPos) {
if(!SS.GW.showConstraints) return;
Group *g = SS.GetGroup(group);
Group *g = SK.GetGroup(group);
// If the group is hidden, then the constraints are hidden and not
// able to be selected.
if(!(g->visible)) return;
@ -210,8 +210,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
glxColor3d(1, 0.1, 1);
switch(type) {
case PT_PT_DISTANCE: {
Vector ap = SS.GetEntity(ptA)->PointGetNum();
Vector bp = SS.GetEntity(ptB)->PointGetNum();
Vector ap = SK.GetEntity(ptA)->PointGetNum();
Vector bp = SK.GetEntity(ptB)->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&ap);
@ -236,8 +236,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PT_FACE_DISTANCE:
case PT_PLANE_DISTANCE: {
Vector pt = SS.GetEntity(ptA)->PointGetNum();
Entity *enta = SS.GetEntity(entityA);
Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *enta = SK.GetEntity(entityA);
Vector n, p;
if(type == PT_PLANE_DISTANCE) {
n = enta->Normal()->NormalN();
@ -258,10 +258,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case PT_LINE_DISTANCE: {
Vector pt = SS.GetEntity(ptA)->PointGetNum();
Entity *line = SS.GetEntity(entityA);
Vector lA = SS.GetEntity(line->point[0])->PointGetNum();
Vector lB = SS.GetEntity(line->point[1])->PointGetNum();
Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *line = SK.GetEntity(entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
lA = lA.ProjectInto(workplane);
@ -282,8 +282,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
Vector lAB = (lA.Minus(lB));
double t = (lA.Minus(closest)).DivPivoting(lAB);
Vector lA = SS.GetEntity(line->point[0])->PointGetNum();
Vector lB = SS.GetEntity(line->point[1])->PointGetNum();
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t));
DoProjectedPoint(&c2);
@ -292,8 +292,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case DIAMETER: {
Entity *circle = SS.GetEntity(entityA);
Vector center = SS.GetEntity(circle->point[0])->PointGetNum();
Entity *circle = SK.GetEntity(entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
double r = circle->CircleGetRadiusNum();
Vector ref = center.Plus(disp.offset);
@ -313,7 +313,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case POINTS_COINCIDENT: {
if(!dogd.drawing) {
for(int i = 0; i < 2; i++) {
Vector p = SS.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
Point2d pp = SS.GW.ProjectPoint(p);
// The point is selected within a radius of 7, from the
// same center; so if the point is visible, then this
@ -328,7 +328,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
Vector r = SS.GW.projRight.ScaledBy((a+1)/SS.GW.scale);
Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale);
for(int i = 0; i < 2; i++) {
Vector p = SS.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
glxColor3d(0.4, 0, 0.4);
glBegin(GL_QUADS);
glxVertex3v(p.Plus (r).Plus (d));
@ -347,14 +347,14 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PT_ON_FACE:
case PT_IN_PLANE: {
double s = 8/SS.GW.scale;
Vector p = SS.GetEntity(ptA)->PointGetNum();
Vector p = SK.GetEntity(ptA)->PointGetNum();
Vector r, d;
if(type == PT_ON_FACE) {
Vector n = SS.GetEntity(entityA)->FaceGetNormalNum();
Vector n = SK.GetEntity(entityA)->FaceGetNormalNum();
r = n.Normal(0);
d = n.Normal(1);
} else if(type == PT_IN_PLANE) {
Entity *n = SS.GetEntity(entityA)->Normal();
Entity *n = SK.GetEntity(entityA)->Normal();
r = n->NormalU();
d = n->NormalV();
} else {
@ -372,11 +372,11 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case SAME_ORIENTATION: {
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
Quaternion q = e->NormalGetNum();
Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale);
Vector u = q.RotationU().WithMagnitude(6/SS.GW.scale);
Vector p = SS.GetEntity(e->point[0])->PointGetNum();
Vector p = SK.GetEntity(e->point[0])->PointGetNum();
p = p.Plus(n.WithMagnitude(10/SS.GW.scale));
LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n));
@ -387,10 +387,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQUAL_ANGLE: {
Vector ref;
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *c = SS.GetEntity(entityC);
Entity *d = SS.GetEntity(entityD);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
Entity *c = SK.GetEntity(entityC);
Entity *d = SK.GetEntity(entityD);
Vector a0 = a->VectorGetRefPoint();
Vector b0 = b->VectorGetRefPoint();
@ -412,8 +412,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case ANGLE: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB);
Vector a0 = a->VectorGetRefPoint();
Vector b0 = b->VectorGetRefPoint();
@ -434,13 +434,13 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
rn = gn;
ru = gu;
} else {
Entity *normal = SS.GetEntity(workplane)->Normal();
Entity *normal = SK.GetEntity(workplane)->Normal();
rn = normal->NormalN();
ru = normal->NormalV(); // ru meaning r_up, not u/v
}
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
if(i == 0) {
// Calculate orientation of perpendicular sign only
@ -469,11 +469,11 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
Vector textAt, u, v;
if(type == ARC_LINE_TANGENT) {
Entity *arc = SS.GetEntity(entityA);
Entity *norm = SS.GetEntity(arc->normal);
Vector c = SS.GetEntity(arc->point[0])->PointGetNum();
Entity *arc = SK.GetEntity(entityA);
Entity *norm = SK.GetEntity(arc->normal);
Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
Vector p =
SS.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
Vector r = p.Minus(c);
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
u = norm->NormalU();
@ -485,16 +485,16 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
v = gu;
n = gn;
} else {
Entity *wn = SS.GetEntity(workplane)->Normal();
Entity *wn = SK.GetEntity(workplane)->Normal();
u = wn->NormalU();
v = wn->NormalV();
n = wn->NormalN();
}
Entity *cubic = SS.GetEntity(entityA);
Entity *cubic = SK.GetEntity(entityA);
Vector p =
SS.GetEntity(cubic->point[other ? 3 : 0])->PointGetNum();
Vector dir = SS.GetEntity(entityB)->VectorGetNum();
SK.GetEntity(cubic->point[other ? 3 : 0])->PointGetNum();
Vector dir = SK.GetEntity(entityB)->VectorGetNum();
Vector out = n.Cross(dir);
textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
}
@ -515,7 +515,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PARALLEL: {
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
Vector n = e->VectorGetNum();
n = n.WithMagnitude(25/SS.GW.scale);
Vector u = (gn.Cross(n)).WithMagnitude(4/SS.GW.scale);
@ -535,10 +535,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case EQUAL_LINE_ARC_LEN: {
Entity *line = SS.GetEntity(entityA);
Entity *line = SK.GetEntity(entityA);
DoEqualLenTicks(
SS.GetEntity(line->point[0])->PointGetNum(),
SS.GetEntity(line->point[1])->PointGetNum(),
SK.GetEntity(line->point[0])->PointGetNum(),
SK.GetEntity(line->point[1])->PointGetNum(),
gn);
DoEqualRadiusTicks(entityB);
@ -549,9 +549,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQUAL_LENGTH_LINES: {
Vector a, b;
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
a = SS.GetEntity(e->point[0])->PointGetNum();
b = SS.GetEntity(e->point[1])->PointGetNum();
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
a = SK.GetEntity(e->point[0])->PointGetNum();
b = SK.GetEntity(e->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&a);
@ -568,19 +568,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case EQ_LEN_PT_LINE_D: {
Entity *forLen = SS.GetEntity(entityA);
Vector a = SS.GetEntity(forLen->point[0])->PointGetNum(),
b = SS.GetEntity(forLen->point[1])->PointGetNum();
Entity *forLen = SK.GetEntity(entityA);
Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
b = SK.GetEntity(forLen->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&a);
DoProjectedPoint(&b);
}
DoEqualLenTicks(a, b, gn);
Entity *ln = SS.GetEntity(entityB);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum();
Vector pt = SS.GetEntity(ptA)->PointGetNum();
Entity *ln = SK.GetEntity(entityB);
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SK.GetEntity(ln->point[1])->PointGetNum();
Vector pt = SK.GetEntity(ptA)->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&pt);
la = la.ProjectInto(workplane);
@ -595,10 +595,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQ_PT_LN_DISTANCES: {
for(int i = 0; i < 2; i++) {
Entity *ln = SS.GetEntity(i == 0 ? entityA : entityB);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum();
Entity *pte = SS.GetEntity(i == 0 ? ptA : ptB);
Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB);
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SK.GetEntity(ln->point[1])->PointGetNum();
Entity *pte = SK.GetEntity(i == 0 ? ptA : ptB);
Vector pt = pte->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) {
@ -618,25 +618,25 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
{
Vector n;
case SYMMETRIC:
n = SS.GetEntity(entityA)->Normal()->NormalN(); goto s;
n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s;
case SYMMETRIC_HORIZ:
n = SS.GetEntity(workplane)->Normal()->NormalU(); goto s;
n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s;
case SYMMETRIC_VERT:
n = SS.GetEntity(workplane)->Normal()->NormalV(); goto s;
n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s;
case SYMMETRIC_LINE: {
Entity *ln = SS.GetEntity(entityA);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum();
Entity *ln = SK.GetEntity(entityA);
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SK.GetEntity(ln->point[1])->PointGetNum();
la = la.ProjectInto(workplane);
lb = lb.ProjectInto(workplane);
n = lb.Minus(la);
Vector nw = SS.GetEntity(workplane)->Normal()->NormalN();
Vector nw = SK.GetEntity(workplane)->Normal()->NormalN();
n = n.RotatedAbout(nw, PI/2);
goto s;
}
s:
Vector a = SS.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum();
Vector a = SK.GetEntity(ptA)->PointGetNum();
Vector b = SK.GetEntity(ptB)->PointGetNum();
for(int i = 0; i < 2; i++) {
Vector tail = (i == 0) ? a : b;
@ -666,14 +666,14 @@ s:
if(workplane.v == Entity::FREE_IN_3D.v) {
r = gr; u = gu; n = gn;
} else {
r = SS.GetEntity(workplane)->Normal()->NormalU();
u = SS.GetEntity(workplane)->Normal()->NormalV();
r = SK.GetEntity(workplane)->Normal()->NormalU();
u = SK.GetEntity(workplane)->Normal()->NormalV();
n = r.Cross(u);
}
// For "at midpoint", this branch is always taken.
Entity *e = SS.GetEntity(entityA);
Vector a = SS.GetEntity(e->point[0])->PointGetNum();
Vector b = SS.GetEntity(e->point[1])->PointGetNum();
Entity *e = SK.GetEntity(entityA);
Vector a = SK.GetEntity(e->point[0])->PointGetNum();
Vector b = SK.GetEntity(e->point[1])->PointGetNum();
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
Vector offset = (a.Minus(b)).Cross(n);
offset = offset.WithMagnitude(13/SS.GW.scale);
@ -696,10 +696,10 @@ s:
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
}
} else {
Vector a = SS.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum();
Vector a = SK.GetEntity(ptA)->PointGetNum();
Vector b = SK.GetEntity(ptB)->PointGetNum();
Entity *w = SS.GetEntity(workplane);
Entity *w = SK.GetEntity(workplane);
Vector cu = w->Normal()->NormalU();
Vector cv = w->Normal()->NormalV();
Vector cn = w->Normal()->NormalN();

View File

@ -2,10 +2,10 @@
char *Entity::DescriptionString(void) {
if(h.isFromRequest()) {
Request *r = SS.GetRequest(h.request());
Request *r = SK.GetRequest(h.request());
return r->DescriptionString();
} else {
Group *g = SS.GetGroup(h.group());
Group *g = SK.GetGroup(h.group());
return g->DescriptionString();
}
}
@ -43,10 +43,10 @@ void Entity::DrawAll(void) {
glxColor3d(0, 0.8, 0);
glxDepthRangeOffset(6);
glBegin(GL_QUADS);
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(!e->IsPoint()) continue;
if(!(SS.GetGroup(e->group)->visible)) continue;
if(!(SK.GetGroup(e->group)->visible)) continue;
if(SS.GroupsInOrder(SS.GW.activeGroup, e->group)) continue;
if(e->forceHidden) continue;
@ -54,14 +54,14 @@ void Entity::DrawAll(void) {
bool free = false;
if(e->type == POINT_IN_3D) {
Param *px = SS.GetParam(e->param[0]),
*py = SS.GetParam(e->param[1]),
*pz = SS.GetParam(e->param[2]);
Param *px = SK.GetParam(e->param[0]),
*py = SK.GetParam(e->param[1]),
*pz = SK.GetParam(e->param[2]);
free = (px->free) || (py->free) || (pz->free);
} else if(e->type == POINT_IN_2D) {
Param *pu = SS.GetParam(e->param[0]),
*pv = SS.GetParam(e->param[1]);
Param *pu = SK.GetParam(e->param[0]),
*pv = SK.GetParam(e->param[1]);
free = (pu->free) || (pv->free);
}
@ -86,8 +86,8 @@ void Entity::DrawAll(void) {
}
glLineWidth(1.5);
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(e->IsPoint())
{
continue; // already handled
@ -145,7 +145,7 @@ Vector Entity::GetReferencePos(void) {
}
bool Entity::IsVisible(void) {
Group *g = SS.GetGroup(group);
Group *g = SK.GetGroup(group);
if(g->h.v == Group::HGROUP_REFERENCES.v && IsNormal()) {
// The reference normals are always shown
@ -178,17 +178,17 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
switch(type) {
case LINE_SEGMENT: {
Vector a = SS.GetEntity(point[0])->PointGetNum();
Vector b = SS.GetEntity(point[1])->PointGetNum();
Vector a = SK.GetEntity(point[0])->PointGetNum();
Vector b = SK.GetEntity(point[1])->PointGetNum();
sb = SBezier::From(a, b);
sbl->l.Add(&sb);
break;
}
case CUBIC: {
Vector p0 = SS.GetEntity(point[0])->PointGetNum();
Vector p1 = SS.GetEntity(point[1])->PointGetNum();
Vector p2 = SS.GetEntity(point[2])->PointGetNum();
Vector p3 = SS.GetEntity(point[3])->PointGetNum();
Vector p0 = SK.GetEntity(point[0])->PointGetNum();
Vector p1 = SK.GetEntity(point[1])->PointGetNum();
Vector p2 = SK.GetEntity(point[2])->PointGetNum();
Vector p3 = SK.GetEntity(point[3])->PointGetNum();
sb = SBezier::From(p0, p1, p2, p3);
sbl->l.Add(&sb);
break;
@ -196,8 +196,8 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
case CIRCLE:
case ARC_OF_CIRCLE: {
Vector center = SS.GetEntity(point[0])->PointGetNum();
Quaternion q = SS.GetEntity(normal)->NormalGetNum();
Vector center = SK.GetEntity(point[0])->PointGetNum();
Quaternion q = SK.GetEntity(normal)->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV();
double r = CircleGetRadiusNum();
double thetaa, thetab, dtheta;
@ -257,8 +257,8 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
}
case TTF_TEXT: {
Vector topLeft = SS.GetEntity(point[0])->PointGetNum();
Vector botLeft = SS.GetEntity(point[1])->PointGetNum();
Vector topLeft = SK.GetEntity(point[0])->PointGetNum();
Vector botLeft = SK.GetEntity(point[1])->PointGetNum();
Vector n = Normal()->NormalN();
Vector v = topLeft.Minus(botLeft);
Vector u = (v.Cross(n)).WithMagnitude(v.Magnitude());
@ -276,7 +276,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
void Entity::DrawOrGetDistance(void) {
if(!IsVisible()) return;
Group *g = SS.GetGroup(group);
Group *g = SK.GetGroup(group);
if(group.v != SS.GW.activeGroup.v) {
glxColor3d(0.5, 0.3, 0.0);
@ -340,7 +340,7 @@ void Entity::DrawOrGetDistance(void) {
Quaternion q = NormalGetNum();
Vector tail;
if(i == 0) {
tail = SS.GetEntity(point[0])->PointGetNum();
tail = SK.GetEntity(point[0])->PointGetNum();
glLineWidth(1);
} else {
// Draw an extra copy of the x, y, and z axes, that's
@ -376,7 +376,7 @@ void Entity::DrawOrGetDistance(void) {
case WORKPLANE: {
Vector p;
p = SS.GetEntity(point[0])->PointGetNum();
p = SK.GetEntity(point[0])->PointGetNum();
Vector u = Normal()->NormalU();
Vector v = Normal()->NormalV();

View File

@ -21,8 +21,8 @@ bool EntityBase::HasVector(void) {
ExprVector EntityBase::VectorGetExprs(void) {
switch(type) {
case LINE_SEGMENT:
return (SS.GetEntity(point[0])->PointGetExprs()).Minus(
SS.GetEntity(point[1])->PointGetExprs());
return (SK.GetEntity(point[0])->PointGetExprs()).Minus(
SK.GetEntity(point[1])->PointGetExprs());
case NORMAL_IN_3D:
case NORMAL_IN_2D:
@ -38,8 +38,8 @@ ExprVector EntityBase::VectorGetExprs(void) {
Vector EntityBase::VectorGetNum(void) {
switch(type) {
case LINE_SEGMENT:
return (SS.GetEntity(point[0])->PointGetNum()).Minus(
SS.GetEntity(point[1])->PointGetNum());
return (SK.GetEntity(point[0])->PointGetNum()).Minus(
SK.GetEntity(point[1])->PointGetNum());
case NORMAL_IN_3D:
case NORMAL_IN_2D:
@ -55,15 +55,15 @@ Vector EntityBase::VectorGetNum(void) {
Vector EntityBase::VectorGetRefPoint(void) {
switch(type) {
case LINE_SEGMENT:
return ((SS.GetEntity(point[0])->PointGetNum()).Plus(
SS.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5);
return ((SK.GetEntity(point[0])->PointGetNum()).Plus(
SK.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5);
case NORMAL_IN_3D:
case NORMAL_IN_2D:
case NORMAL_N_COPY:
case NORMAL_N_ROT:
case NORMAL_N_ROT_AA:
return SS.GetEntity(point[0])->PointGetNum();
return SK.GetEntity(point[0])->PointGetNum();
default: oops();
}
@ -75,7 +75,7 @@ bool EntityBase::IsCircle(void) {
Expr *EntityBase::CircleGetRadiusExpr(void) {
if(type == CIRCLE) {
return SS.GetEntity(distance)->DistanceGetExpr();
return SK.GetEntity(distance)->DistanceGetExpr();
} else if(type == ARC_OF_CIRCLE) {
return Constraint::Distance(workplane, point[0], point[1]);
} else oops();
@ -83,10 +83,10 @@ Expr *EntityBase::CircleGetRadiusExpr(void) {
double EntityBase::CircleGetRadiusNum(void) {
if(type == CIRCLE) {
return SS.GetEntity(distance)->DistanceGetNum();
return SK.GetEntity(distance)->DistanceGetNum();
} else if(type == ARC_OF_CIRCLE) {
Vector c = SS.GetEntity(point[0])->PointGetNum();
Vector pa = SS.GetEntity(point[1])->PointGetNum();
Vector c = SK.GetEntity(point[0])->PointGetNum();
Vector pa = SK.GetEntity(point[1])->PointGetNum();
return (pa.Minus(c)).Magnitude();
} else oops();
}
@ -97,9 +97,9 @@ void EntityBase::ArcGetAngles(double *thetaa, double *thetab, double *dtheta) {
Quaternion q = Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV();
Vector c = SS.GetEntity(point[0])->PointGetNum();
Vector pa = SS.GetEntity(point[1])->PointGetNum();
Vector pb = SS.GetEntity(point[2])->PointGetNum();
Vector c = SK.GetEntity(point[0])->PointGetNum();
Vector pa = SK.GetEntity(point[1])->PointGetNum();
Vector pb = SK.GetEntity(point[2])->PointGetNum();
Point2d c2 = c.Project2d(u, v);
Point2d pa2 = (pa.Project2d(u, v)).Minus(c2);
@ -119,18 +119,18 @@ bool EntityBase::IsWorkplane(void) {
}
ExprVector EntityBase::WorkplaneGetOffsetExprs(void) {
return SS.GetEntity(point[0])->PointGetExprs();
return SK.GetEntity(point[0])->PointGetExprs();
}
Vector EntityBase::WorkplaneGetOffset(void) {
return SS.GetEntity(point[0])->PointGetNum();
return SK.GetEntity(point[0])->PointGetNum();
}
void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) {
if(type == WORKPLANE) {
*n = Normal()->NormalExprsN();
ExprVector p0 = SS.GetEntity(point[0])->PointGetExprs();
ExprVector p0 = SK.GetEntity(point[0])->PointGetExprs();
// The plane is n dot (p - p0) = 0, or
// n dot p - n dot p0 = 0
// so dn = n dot p0
@ -142,7 +142,7 @@ void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) {
double EntityBase::DistanceGetNum(void) {
if(type == DISTANCE) {
return SS.GetParam(param[0])->val;
return SK.GetParam(param[0])->val;
} else if(type == DISTANCE_N_COPY) {
return numDistance;
} else oops();
@ -156,14 +156,14 @@ Expr *EntityBase::DistanceGetExpr(void) {
}
void EntityBase::DistanceForceTo(double v) {
if(type == DISTANCE) {
(SS.GetParam(param[0]))->val = v;
(SK.GetParam(param[0]))->val = v;
} else if(type == DISTANCE_N_COPY) {
// do nothing, it's locked
} else oops();
}
Entity *EntityBase::Normal(void) {
return SS.GetEntity(normal);
return SK.GetEntity(normal);
}
bool EntityBase::IsPoint(void) {
@ -202,8 +202,8 @@ Quaternion EntityBase::NormalGetNum(void) {
break;
case NORMAL_IN_2D: {
Entity *wrkpl = SS.GetEntity(workplane);
Entity *norm = SS.GetEntity(wrkpl->normal);
Entity *wrkpl = SK.GetEntity(workplane);
Entity *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetNum();
break;
}
@ -230,10 +230,10 @@ Quaternion EntityBase::NormalGetNum(void) {
void EntityBase::NormalForceTo(Quaternion q) {
switch(type) {
case NORMAL_IN_3D:
SS.GetParam(param[0])->val = q.w;
SS.GetParam(param[1])->val = q.vx;
SS.GetParam(param[2])->val = q.vy;
SS.GetParam(param[3])->val = q.vz;
SK.GetParam(param[0])->val = q.w;
SK.GetParam(param[1])->val = q.vx;
SK.GetParam(param[2])->val = q.vy;
SK.GetParam(param[3])->val = q.vz;
break;
case NORMAL_IN_2D:
@ -243,10 +243,10 @@ void EntityBase::NormalForceTo(Quaternion q) {
case NORMAL_N_ROT: {
Quaternion qp = q.Times(numNormal.Inverse());
SS.GetParam(param[0])->val = qp.w;
SS.GetParam(param[1])->val = qp.vx;
SS.GetParam(param[2])->val = qp.vy;
SS.GetParam(param[3])->val = qp.vz;
SK.GetParam(param[0])->val = qp.w;
SK.GetParam(param[1])->val = qp.vx;
SK.GetParam(param[2])->val = qp.vy;
SK.GetParam(param[3])->val = qp.vz;
break;
}
@ -286,8 +286,8 @@ ExprQuaternion EntityBase::NormalGetExprs(void) {
break;
case NORMAL_IN_2D: {
Entity *wrkpl = SS.GetEntity(workplane);
Entity *norm = SS.GetEntity(wrkpl->normal);
Entity *wrkpl = SK.GetEntity(workplane);
Entity *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetExprs();
break;
}
@ -322,25 +322,25 @@ bool EntityBase::PointIsFromReferences(void) {
void EntityBase::PointForceTo(Vector p) {
switch(type) {
case POINT_IN_3D:
SS.GetParam(param[0])->val = p.x;
SS.GetParam(param[1])->val = p.y;
SS.GetParam(param[2])->val = p.z;
SK.GetParam(param[0])->val = p.x;
SK.GetParam(param[1])->val = p.y;
SK.GetParam(param[2])->val = p.z;
break;
case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane);
Entity *c = SK.GetEntity(workplane);
p = p.Minus(c->WorkplaneGetOffset());
SS.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU());
SS.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV());
SK.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU());
SK.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV());
break;
}
case POINT_N_TRANS: {
if(timesApplied == 0) break;
Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
SS.GetParam(param[0])->val = trans.x;
SS.GetParam(param[1])->val = trans.y;
SS.GetParam(param[2])->val = trans.z;
SK.GetParam(param[0])->val = trans.x;
SK.GetParam(param[1])->val = trans.y;
SK.GetParam(param[2])->val = trans.z;
break;
}
@ -349,9 +349,9 @@ void EntityBase::PointForceTo(Vector p) {
// remember that we're working with respect to the rotated
// point.
Vector trans = p.Minus(PointGetQuaternion().Rotate(numPoint));
SS.GetParam(param[0])->val = trans.x;
SS.GetParam(param[1])->val = trans.y;
SS.GetParam(param[2])->val = trans.z;
SK.GetParam(param[0])->val = trans.x;
SK.GetParam(param[1])->val = trans.y;
SK.GetParam(param[2])->val = trans.z;
break;
}
@ -364,13 +364,13 @@ void EntityBase::PointForceTo(Vector p) {
double thetap = atan2(v.Dot(po), u.Dot(po));
double thetan = atan2(v.Dot(numo), u.Dot(numo));
double thetaf = (thetap - thetan);
double thetai = (SS.GetParam(param[3])->val)*timesApplied*2;
double thetai = (SK.GetParam(param[3])->val)*timesApplied*2;
double dtheta = thetaf - thetai;
// Take the smallest possible change in the actual step angle,
// in order to avoid jumps when you cross from +pi to -pi
while(dtheta < -PI) dtheta += 2*PI;
while(dtheta > PI) dtheta -= 2*PI;
SS.GetParam(param[3])->val = (thetai + dtheta)/(timesApplied*2);
SK.GetParam(param[3])->val = (thetai + dtheta)/(timesApplied*2);
break;
}
@ -390,11 +390,11 @@ Vector EntityBase::PointGetNum(void) {
break;
case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane);
Entity *c = SK.GetEntity(workplane);
Vector u = c->Normal()->NormalU();
Vector v = c->Normal()->NormalV();
p = u.ScaledBy(SS.GetParam(param[0])->val);
p = p.Plus(v.ScaledBy(SS.GetParam(param[1])->val));
p = u.ScaledBy(SK.GetParam(param[0])->val);
p = p.Plus(v.ScaledBy(SK.GetParam(param[1])->val));
p = p.Plus(c->WorkplaneGetOffset());
break;
}
@ -439,7 +439,7 @@ ExprVector EntityBase::PointGetExprs(void) {
break;
case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane);
Entity *c = SK.GetEntity(workplane);
ExprVector u = c->Normal()->NormalExprsU();
ExprVector v = c->Normal()->NormalExprsV();
r = c->WorkplaneGetOffsetExprs();
@ -488,7 +488,7 @@ void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) {
*v = Expr::From(param[1]);
} else {
// Get the offset and basis vectors for this weird exotic csys.
Entity *w = SS.GetEntity(wrkpl);
Entity *w = SK.GetEntity(wrkpl);
ExprVector wp = w->WorkplaneGetOffsetExprs();
ExprVector wu = w->Normal()->NormalExprsU();
ExprVector wv = w->Normal()->NormalExprsV();
@ -505,20 +505,20 @@ void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) {
void EntityBase::PointForceQuaternionTo(Quaternion q) {
if(type != POINT_N_ROT_TRANS) oops();
SS.GetParam(param[3])->val = q.w;
SS.GetParam(param[4])->val = q.vx;
SS.GetParam(param[5])->val = q.vy;
SS.GetParam(param[6])->val = q.vz;
SK.GetParam(param[3])->val = q.w;
SK.GetParam(param[4])->val = q.vx;
SK.GetParam(param[5])->val = q.vy;
SK.GetParam(param[6])->val = q.vz;
}
Quaternion EntityBase::GetAxisAngleQuaternion(int param0) {
Quaternion q;
double theta = timesApplied*SS.GetParam(param[param0+0])->val;
double theta = timesApplied*SK.GetParam(param[param0+0])->val;
double s = sin(theta), c = cos(theta);
q.w = c;
q.vx = s*SS.GetParam(param[param0+1])->val;
q.vy = s*SS.GetParam(param[param0+2])->val;
q.vz = s*SS.GetParam(param[param0+3])->val;
q.vx = s*SK.GetParam(param[param0+1])->val;
q.vy = s*SK.GetParam(param[param0+2])->val;
q.vz = s*SK.GetParam(param[param0+3])->val;
return q;
}
@ -615,7 +615,7 @@ Vector EntityBase::FaceGetNormalNum(void) {
ExprVector EntityBase::FaceGetPointExprs(void) {
ExprVector r;
if(type == FACE_NORMAL_PT) {
r = SS.GetEntity(point[0])->PointGetExprs();
r = SK.GetEntity(point[0])->PointGetExprs();
} else if(type == FACE_XPROD) {
r = ExprVector::From(numPoint);
} else if(type == FACE_N_ROT_TRANS) {
@ -644,7 +644,7 @@ ExprVector EntityBase::FaceGetPointExprs(void) {
Vector EntityBase::FaceGetPointNum(void) {
Vector r;
if(type == FACE_NORMAL_PT) {
r = SS.GetEntity(point[0])->PointGetNum();
r = SK.GetEntity(point[0])->PointGetNum();
} else if(type == FACE_XPROD) {
r = numPoint;
} else if(type == FACE_N_ROT_TRANS) {
@ -684,7 +684,7 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) {
// If this is a copied entity, with its point already fixed
// with respect to each other, then we don't want to generate
// the distance constraint!
if(SS.GetEntity(point[0])->type == POINT_IN_2D) {
if(SK.GetEntity(point[0])->type == POINT_IN_2D) {
Expr *ra = Constraint::Distance(workplane, point[0], point[1]);
Expr *rb = Constraint::Distance(workplane, point[0], point[2]);
AddEq(l, ra->Minus(rb), 0);

View File

@ -5,7 +5,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
gn = gn.WithMagnitude(1);
Group *g = SS.GetGroup(SS.GW.activeGroup);
Group *g = SK.GetGroup(SS.GW.activeGroup);
if(g->runningMesh.l.n == 0) {
Error("No solid model present; draw one with extrudes and revolves, "
"or use Export 2d View to export bare lines and curves.");
@ -20,21 +20,21 @@ void SolveSpace::ExportSectionTo(char *filename) {
SS.GW.GroupSelection();
#define gs (SS.GW.gs)
if((gs.n == 0 && g->activeWorkplane.v != Entity::FREE_IN_3D.v)) {
Entity *wrkpl = SS.GetEntity(g->activeWorkplane);
Entity *wrkpl = SK.GetEntity(g->activeWorkplane);
origin = wrkpl->WorkplaneGetOffset();
n = wrkpl->Normal()->NormalN();
u = wrkpl->Normal()->NormalU();
v = wrkpl->Normal()->NormalV();
} else if(gs.n == 1 && gs.faces == 1) {
Entity *face = SS.GetEntity(gs.entity[0]);
Entity *face = SK.GetEntity(gs.entity[0]);
origin = face->FaceGetPointNum();
n = face->FaceGetNormalNum();
if(n.Dot(gn) < 0) n = n.ScaledBy(-1);
u = n.Normal(0);
v = n.Normal(1);
} else if(gs.n == 3 && gs.vectors == 2 && gs.points == 1) {
Vector ut = SS.GetEntity(gs.entity[0])->VectorGetNum(),
vt = SS.GetEntity(gs.entity[1])->VectorGetNum();
Vector ut = SK.GetEntity(gs.entity[0])->VectorGetNum(),
vt = SK.GetEntity(gs.entity[1])->VectorGetNum();
ut = ut.WithMagnitude(1);
vt = vt.WithMagnitude(1);
@ -44,7 +44,7 @@ void SolveSpace::ExportSectionTo(char *filename) {
if(SS.GW.projRight.Dot(ut) < 0) ut = ut.ScaledBy(-1);
if(SS.GW.projUp. Dot(vt) < 0) vt = vt.ScaledBy(-1);
origin = SS.GetEntity(gs.point[0])->PointGetNum();
origin = SK.GetEntity(gs.point[0])->PointGetNum();
n = ut.Cross(vt);
u = ut.WithMagnitude(1);
v = (n.Cross(u)).WithMagnitude(1);
@ -95,14 +95,14 @@ void SolveSpace::ExportViewTo(char *filename) {
SMesh *sm = NULL;
if(SS.GW.showShaded) {
sm = &((SS.GetGroup(SS.GW.activeGroup))->runningMesh);
sm = &((SK.GetGroup(SS.GW.activeGroup))->runningMesh);
}
if(sm->l.n == 0) {
sm = NULL;
}
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(!e->IsVisible()) continue;
if(e->construction) continue;
@ -119,7 +119,7 @@ void SolveSpace::ExportViewTo(char *filename) {
}
if(SS.GW.showEdges) {
SEdgeList *selr = &((SS.GetGroup(SS.GW.activeGroup))->runningEdges);
SEdgeList *selr = &((SK.GetGroup(SS.GW.activeGroup))->runningEdges);
SEdge *se;
for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
edges.AddEdge(se->a, se->b);
@ -973,7 +973,7 @@ void HpglFileWriter::FinishAndCloseFile(void) {
// not self-intersecting, so not much to do.
//-----------------------------------------------------------------------------
void SolveSpace::ExportMeshTo(char *filename) {
SMesh *m = &(SS.GetGroup(SS.GW.activeGroup)->runningMesh);
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
if(m->l.n == 0) {
Error("Active group mesh is empty; nothing to export.");
return;

View File

@ -299,7 +299,7 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
double Expr::Eval(void) {
switch(op) {
case PARAM: return SS.GetParam(x.parh)->val;
case PARAM: return SK.GetParam(x.parh)->val;
case PARAM_PTR: return (x.parp)->val;
case CONSTANT: return x.v;

View File

@ -14,8 +14,8 @@ hGroup SolveSpace::CreateDefaultDrawingGroup(void) {
hRequest hr = Request::HREQUEST_REFERENCE_XY;
g.predef.origin = hr.entity(1);
g.name.strcpy("sketch-in-plane");
group.AddAndAssignId(&g);
SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
SK.group.AddAndAssignId(&g);
SK.GetGroup(g.h)->activeWorkplane = g.h.entity(0);
return g.h;
}
@ -23,12 +23,12 @@ void SolveSpace::NewFile(void) {
UndoClearStack(&redo);
UndoClearStack(&undo);
constraint.Clear();
request.Clear();
group.Clear();
SK.constraint.Clear();
SK.request.Clear();
SK.group.Clear();
entity.Clear();
param.Clear();
SK.entity.Clear();
SK.param.Clear();
// Our initial group, that contains the references.
Group g;
@ -37,7 +37,7 @@ void SolveSpace::NewFile(void) {
g.name.strcpy("#references");
g.type = Group::DRAWING_3D;
g.h = Group::HGROUP_REFERENCES;
group.Add(&g);
SK.group.Add(&g);
// Let's create three two-d coordinate systems, for the coordinate
// planes; these are our references, present in every sketch.
@ -48,13 +48,13 @@ void SolveSpace::NewFile(void) {
r.workplane = Entity::FREE_IN_3D;
r.h = Request::HREQUEST_REFERENCE_XY;
request.Add(&r);
SK.request.Add(&r);
r.h = Request::HREQUEST_REFERENCE_YZ;
request.Add(&r);
SK.request.Add(&r);
r.h = Request::HREQUEST_REFERENCE_ZX;
request.Add(&r);
SK.request.Add(&r);
CreateDefaultDrawingGroup();
}
@ -200,38 +200,38 @@ bool SolveSpace::SaveToFile(char *filename) {
fprintf(fh, "%s\n\n\n", VERSION_STRING);
int i;
for(i = 0; i < group.n; i++) {
sv.g = group.elem[i];
for(i = 0; i < SK.group.n; i++) {
sv.g = SK.group.elem[i];
SaveUsingTable('g');
fprintf(fh, "AddGroup\n\n");
}
for(i = 0; i < param.n; i++) {
sv.p = param.elem[i];
for(i = 0; i < SK.param.n; i++) {
sv.p = SK.param.elem[i];
SaveUsingTable('p');
fprintf(fh, "AddParam\n\n");
}
for(i = 0; i < request.n; i++) {
sv.r = request.elem[i];
for(i = 0; i < SK.request.n; i++) {
sv.r = SK.request.elem[i];
SaveUsingTable('r');
fprintf(fh, "AddRequest\n\n");
}
for(i = 0; i < entity.n; i++) {
(entity.elem[i]).CalculateNumerical(true);
sv.e = entity.elem[i];
for(i = 0; i < SK.entity.n; i++) {
(SK.entity.elem[i]).CalculateNumerical(true);
sv.e = SK.entity.elem[i];
SaveUsingTable('e');
fprintf(fh, "AddEntity\n\n");
}
for(i = 0; i < constraint.n; i++) {
sv.c = constraint.elem[i];
for(i = 0; i < SK.constraint.n; i++) {
sv.c = SK.constraint.elem[i];
SaveUsingTable('c');
fprintf(fh, "AddConstraint\n\n");
}
SMesh *m = &(group.elem[group.n-1].runningMesh);
SMesh *m = &(SK.group.elem[SK.group.n-1].runningMesh);
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
fprintf(fh, "Triangle %08x %08x "
@ -304,11 +304,11 @@ bool SolveSpace::LoadFromFile(char *filename) {
UndoClearStack(&redo);
UndoClearStack(&undo);
constraint.Clear();
request.Clear();
group.Clear();
entity.Clear();
param.Clear();
SK.constraint.Clear();
SK.request.Clear();
SK.group.Clear();
SK.entity.Clear();
SK.param.Clear();
memset(&sv, 0, sizeof(sv));
char line[1024];
@ -328,20 +328,20 @@ bool SolveSpace::LoadFromFile(char *filename) {
char *key = line, *val = e+1;
LoadUsingTable(key, val);
} else if(strcmp(line, "AddGroup")==0) {
SS.group.Add(&(sv.g));
SK.group.Add(&(sv.g));
memset(&(sv.g), 0, sizeof(sv.g));
} else if(strcmp(line, "AddParam")==0) {
// params are regenerated, but we want to preload the values
// for initial guesses
SS.param.Add(&(sv.p));
SK.param.Add(&(sv.p));
memset(&(sv.p), 0, sizeof(sv.p));
} else if(strcmp(line, "AddEntity")==0) {
// entities are regenerated
} else if(strcmp(line, "AddRequest")==0) {
SS.request.Add(&(sv.r));
SK.request.Add(&(sv.r));
memset(&(sv.r), 0, sizeof(sv.r));
} else if(strcmp(line, "AddConstraint")==0) {
SS.constraint.Add(&(sv.c));
SK.constraint.Add(&(sv.c));
memset(&(sv.c), 0, sizeof(sv.c));
} else if(strcmp(line, VERSION_STRING)==0) {
// do nothing, version string
@ -420,8 +420,8 @@ void SolveSpace::ReloadAllImported(void) {
allConsistent = false;
int i;
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
if(g->type != Group::IMPORTED) continue;
g->impEntity.Clear();

View File

@ -1,15 +1,15 @@
#include "solvespace.h"
void SolveSpace::MarkGroupDirtyByEntity(hEntity he) {
Entity *e = SS.GetEntity(he);
Entity *e = SK.GetEntity(he);
MarkGroupDirty(e->group);
}
void SolveSpace::MarkGroupDirty(hGroup hg) {
int i;
bool go = false;
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
if(g->h.v == hg.v) {
go = true;
}
@ -22,23 +22,23 @@ void SolveSpace::MarkGroupDirty(hGroup hg) {
bool SolveSpace::PruneOrphans(void) {
int i;
for(i = 0; i < request.n; i++) {
Request *r = &(request.elem[i]);
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(GroupExists(r->group)) continue;
(deleted.requests)++;
request.RemoveById(r->h);
SK.request.RemoveById(r->h);
return true;
}
for(i = 0; i < constraint.n; i++) {
Constraint *c = &(constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(GroupExists(c->group)) continue;
(deleted.constraints)++;
(deleted.nonTrivialConstraints)++;
constraint.RemoveById(c->h);
SK.constraint.RemoveById(c->h);
return true;
}
return false;
@ -50,8 +50,8 @@ bool SolveSpace::GroupsInOrder(hGroup before, hGroup after) {
int beforep = -1, afterp = -1;
int i;
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
if(g->h.v == before.v) beforep = i;
if(g->h.v == after.v) afterp = i;
}
@ -62,17 +62,17 @@ bool SolveSpace::GroupsInOrder(hGroup before, hGroup after) {
bool SolveSpace::GroupExists(hGroup hg) {
// A nonexistent group is not acceptable
return group.FindByIdNoOops(hg) ? true : false;
return SK.group.FindByIdNoOops(hg) ? true : false;
}
bool SolveSpace::EntityExists(hEntity he) {
// A nonexstient entity is acceptable, though, usually just means it
// doesn't apply.
if(he.v == Entity::NO_ENTITY.v) return true;
return entity.FindByIdNoOops(he) ? true : false;
return SK.entity.FindByIdNoOops(he) ? true : false;
}
bool SolveSpace::PruneGroups(hGroup hg) {
Group *g = GetGroup(hg);
Group *g = SK.GetGroup(hg);
if(GroupsInOrder(g->opA, hg) &&
EntityExists(g->predef.origin) &&
EntityExists(g->predef.entityB) &&
@ -81,14 +81,14 @@ bool SolveSpace::PruneGroups(hGroup hg) {
return false;
}
(deleted.groups)++;
group.RemoveById(g->h);
SK.group.RemoveById(g->h);
return true;
}
bool SolveSpace::PruneRequests(hGroup hg) {
int i;
for(i = 0; i < entity.n; i++) {
Entity *e = &(entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(e->group.v != hg.v) continue;
if(EntityExists(e->workplane)) continue;
@ -96,7 +96,7 @@ bool SolveSpace::PruneRequests(hGroup hg) {
if(!e->h.isFromRequest()) oops();
(deleted.requests)++;
request.RemoveById(e->h.request());
SK.request.RemoveById(e->h.request());
return true;
}
return false;
@ -104,8 +104,8 @@ bool SolveSpace::PruneRequests(hGroup hg) {
bool SolveSpace::PruneConstraints(hGroup hg) {
int i;
for(i = 0; i < constraint.n; i++) {
Constraint *c = &(constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->group.v != hg.v) continue;
if(EntityExists(c->workplane) &&
@ -127,7 +127,7 @@ bool SolveSpace::PruneConstraints(hGroup hg) {
(deleted.nonTrivialConstraints)++;
}
constraint.RemoveById(c->h);
SK.constraint.RemoveById(c->h);
return true;
}
return false;
@ -138,8 +138,8 @@ void SolveSpace::GenerateAll(void) {
int firstDirty = INT_MAX, lastVisible = 0;
// Start from the first dirty group, and solve until the active group,
// since all groups after the active group are hidden.
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
g->order = i;
if((!g->clean) || (g->solved.how != Group::SOLVED_OKAY)) {
firstDirty = min(firstDirty, i);
@ -167,11 +167,11 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
// Don't lose our numerical guesses when we regenerate.
IdList<Param,hParam> prev;
param.MoveSelfInto(&prev);
entity.Clear();
SK.param.MoveSelfInto(&prev);
SK.entity.Clear();
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
// The group may depend on entities or other groups, to define its
// workplane geometry or for its operands. Those must already exist
@ -179,13 +179,13 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
if(PruneGroups(g->h))
goto pruned;
for(j = 0; j < request.n; j++) {
Request *r = &(request.elem[j]);
for(j = 0; j < SK.request.n; j++) {
Request *r = &(SK.request.elem[j]);
if(r->group.v != g->h.v) continue;
r->Generate(&entity, &param);
r->Generate(&(SK.entity), &(SK.param));
}
g->Generate(&entity, &param);
g->Generate(&(SK.entity), &(SK.param));
// The requests and constraints depend on stuff in this or the
// previous group, so check them after generating.
@ -194,8 +194,8 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
// Use the previous values for params that we've seen before, as
// initial guesses for the solver.
for(j = 0; j < param.n; j++) {
Param *newp = &(param.elem[j]);
for(j = 0; j < SK.param.n; j++) {
Param *newp = &(SK.param.elem[j]);
if(newp->known) continue;
Param *prevp = prev.FindByIdNoOops(newp->h);
@ -218,8 +218,8 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
// The group falls outside the range, so just assume that
// it's good wherever we left it. The mesh is unchanged,
// and the parameters must be marked as known.
for(j = 0; j < param.n; j++) {
Param *newp = &(param.elem[j]);
for(j = 0; j < SK.param.n; j++) {
Param *newp = &(SK.param.elem[j]);
Param *prevp = prev.FindByIdNoOops(newp->h);
if(prevp) newp->known = true;
@ -229,20 +229,20 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
}
// And update any reference dimensions with their new values
for(i = 0; i < constraint.n; i++) {
Constraint *c = &(constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->reference) {
c->ModifyToSatisfy();
}
}
// Make sure the point that we're tracing exists.
if(traced.point.v && !entity.FindByIdNoOops(traced.point)) {
if(traced.point.v && !SK.entity.FindByIdNoOops(traced.point)) {
traced.point = Entity::NO_ENTITY;
}
// And if we're tracing a point, add its new value to the path
if(traced.point.v) {
Entity *pt = GetEntity(traced.point);
Entity *pt = SK.GetEntity(traced.point);
traced.path.AddPoint(pt->PointGetNum());
}
@ -294,8 +294,8 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) {
pruned:
// Restore the numerical guesses
param.Clear();
prev.MoveSelfInto(&param);
SK.param.Clear();
prev.MoveSelfInto(&(SK.param));
// Try again
GenerateAll(first, last);
}
@ -313,20 +313,20 @@ void SolveSpace::ForceReferences(void) {
};
for(int i = 0; i < 3; i++) {
hRequest hr = Quat[i].hr;
Entity *wrkpl = GetEntity(hr.entity(0));
Entity *wrkpl = SK.GetEntity(hr.entity(0));
// The origin for our coordinate system, always zero
Entity *origin = GetEntity(wrkpl->point[0]);
Entity *origin = SK.GetEntity(wrkpl->point[0]);
origin->PointForceTo(Vector::From(0, 0, 0));
GetParam(origin->param[0])->known = true;
GetParam(origin->param[1])->known = true;
GetParam(origin->param[2])->known = true;
SK.GetParam(origin->param[0])->known = true;
SK.GetParam(origin->param[1])->known = true;
SK.GetParam(origin->param[2])->known = true;
// The quaternion that defines the rotation, from the table.
Entity *normal = GetEntity(wrkpl->normal);
Entity *normal = SK.GetEntity(wrkpl->normal);
normal->NormalForceTo(Quat[i].q);
GetParam(normal->param[0])->known = true;
GetParam(normal->param[1])->known = true;
GetParam(normal->param[2])->known = true;
GetParam(normal->param[3])->known = true;
SK.GetParam(normal->param[0])->known = true;
SK.GetParam(normal->param[1])->known = true;
SK.GetParam(normal->param[2])->known = true;
SK.GetParam(normal->param[3])->known = true;
}
}
@ -337,20 +337,20 @@ void SolveSpace::SolveGroup(hGroup hg, bool andFindFree) {
sys.param.Clear();
sys.eq.Clear();
// And generate all the params for requests in this group
for(i = 0; i < request.n; i++) {
Request *r = &(request.elem[i]);
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(r->group.v != hg.v) continue;
r->Generate(&(sys.entity), &(sys.param));
}
// And for the group itself
Group *g = SS.GetGroup(hg);
Group *g = SK.GetGroup(hg);
g->Generate(&(sys.entity), &(sys.param));
// Set the initial guesses for all the params
for(i = 0; i < sys.param.n; i++) {
Param *p = &(sys.param.elem[i]);
p->known = false;
p->val = GetParam(p->h)->val;
p->val = SK.GetParam(p->h)->val;
}
sys.Solve(g, andFindFree);
@ -360,8 +360,8 @@ void SolveSpace::SolveGroup(hGroup hg, bool andFindFree) {
bool SolveSpace::AllGroupsOkay(void) {
int i;
bool allOk = true;
for(i = 0; i < group.n; i++) {
if(group.elem[i].solved.how != Group::SOLVED_OKAY) {
for(i = 0; i < SK.group.n; i++) {
if(SK.group.elem[i].solved.how != Group::SOLVED_OKAY) {
allOk = false;
}
}

View File

@ -302,6 +302,13 @@ void glxDrawEdges(SEdgeList *el)
glxVertex3v(se->b);
}
glEnd();
glPointSize(12);
glBegin(GL_POINTS);
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
glxVertex3v(se->a);
glxVertex3v(se->b);
}
glEnd();
}
void glxDebugMesh(SMesh *m)

View File

@ -136,8 +136,8 @@ void GraphicsWindow::Init(void) {
orig.projUp = projUp;
// And with the last group active
activeGroup = SS.group.elem[SS.group.n-1].h;
SS.GetGroup(activeGroup)->Activate();
activeGroup = SK.group.elem[SK.group.n-1].h;
SK.GetGroup(activeGroup)->Activate();
showWorkplanes = false;
showNormals = true;
@ -201,9 +201,9 @@ Vector GraphicsWindow::ProjectPoint4(Vector p, double *w) {
void GraphicsWindow::AnimateOntoWorkplane(void) {
if(!LockedInWorkplane()) return;
Entity *w = SS.GetEntity(ActiveWorkplane());
Entity *w = SK.GetEntity(ActiveWorkplane());
Quaternion quatf = w->Normal()->NormalGetNum();
Vector offsetf = (SS.GetEntity(w->point[0])->PointGetNum()).ScaledBy(-1);
Vector offsetf = (SK.GetEntity(w->point[0])->PointGetNum()).ScaledBy(-1);
AnimateOnto(quatf, offsetf);
}
@ -268,8 +268,8 @@ void GraphicsWindow::LoopOverPoints(
HandlePointForZoomToFit(Vector::From(0, 0, 0), pmax, pmin, wmin, div);
int i, j;
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(!e->IsVisible()) continue;
if(e->IsPoint()) {
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, div);
@ -279,8 +279,8 @@ void GraphicsWindow::LoopOverPoints(
// reasonable without the mesh, because a zoom to fit is used to
// set the zoom level to set the chord tol.
double r = e->CircleGetRadiusNum();
Vector c = SS.GetEntity(e->point[0])->PointGetNum();
Quaternion q = SS.GetEntity(e->normal)->NormalGetNum();
Vector c = SK.GetEntity(e->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(e->normal)->NormalGetNum();
for(j = 0; j < 4; j++) {
Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) :
(j == 1) ? (c.Plus(q.RotationU().ScaledBy(-r))) :
@ -290,7 +290,7 @@ void GraphicsWindow::LoopOverPoints(
}
}
}
Group *g = SS.GetGroup(activeGroup);
Group *g = SK.GetGroup(activeGroup);
for(i = 0; i < g->runningMesh.l.n; i++) {
STriangle *tr = &(g->runningMesh.l.elem[i]);
HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, div);
@ -420,7 +420,7 @@ void GraphicsWindow::MenuView(int id) {
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
Quaternion quat0;
// Offset is the selected point, quaternion is same as before
Vector pt = SS.GetEntity(SS.GW.gs.point[0])->PointGetNum();
Vector pt = SK.GetEntity(SS.GW.gs.point[0])->PointGetNum();
quat0 = Quaternion::From(SS.GW.projRight, SS.GW.projUp);
SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1));
SS.GW.ClearSelection();
@ -461,15 +461,15 @@ void GraphicsWindow::MenuView(int id) {
void GraphicsWindow::EnsureValidActives(void) {
bool change = false;
// The active group must exist, and not be the references.
Group *g = SS.group.FindByIdNoOops(activeGroup);
Group *g = SK.group.FindByIdNoOops(activeGroup);
if((!g) || (g->h.v == Group::HGROUP_REFERENCES.v)) {
int i;
for(i = 0; i < SS.group.n; i++) {
if(SS.group.elem[i].h.v != Group::HGROUP_REFERENCES.v) {
for(i = 0; i < SK.group.n; i++) {
if(SK.group.elem[i].h.v != Group::HGROUP_REFERENCES.v) {
break;
}
}
if(i >= SS.group.n) {
if(i >= SK.group.n) {
// This can happen if the user deletes all the groups in the
// sketch. It's difficult to prevent that, because the last
// group might have been deleted automatically, because it failed
@ -478,15 +478,15 @@ void GraphicsWindow::EnsureValidActives(void) {
// to delete the references, though.
activeGroup = SS.CreateDefaultDrawingGroup();
} else {
activeGroup = SS.group.elem[i].h;
activeGroup = SK.group.elem[i].h;
}
SS.GetGroup(activeGroup)->Activate();
SK.GetGroup(activeGroup)->Activate();
change = true;
}
// The active coordinate system must also exist.
if(LockedInWorkplane()) {
Entity *e = SS.entity.FindByIdNoOops(ActiveWorkplane());
Entity *e = SK.entity.FindByIdNoOops(ActiveWorkplane());
if(e) {
hGroup hgw = e->group;
if(hgw.v != activeGroup.v && SS.GroupsInOrder(activeGroup, hgw)) {
@ -527,10 +527,10 @@ void GraphicsWindow::EnsureValidActives(void) {
}
void GraphicsWindow::SetWorkplaneFreeIn3d(void) {
SS.GetGroup(activeGroup)->activeWorkplane = Entity::FREE_IN_3D;
SK.GetGroup(activeGroup)->activeWorkplane = Entity::FREE_IN_3D;
}
hEntity GraphicsWindow::ActiveWorkplane(void) {
Group *g = SS.group.FindByIdNoOops(activeGroup);
Group *g = SK.group.FindByIdNoOops(activeGroup);
if(g) {
return g->activeWorkplane;
} else {
@ -550,7 +550,7 @@ void GraphicsWindow::ForceTextWindowShown(void) {
}
void GraphicsWindow::DeleteTaggedRequests(void) {
SS.request.RemoveTagged();
SK.request.RemoveTagged();
// An edit might be in progress for the just-deleted item. So
// now it's not.
@ -583,8 +583,8 @@ void GraphicsWindow::MenuEdit(int id) {
SS.UndoRemember();
int i;
SS.request.ClearTags();
SS.constraint.ClearTags();
SK.request.ClearTags();
SK.constraint.ClearTags();
for(i = 0; i < MAX_SELECTED; i++) {
Selection *s = &(SS.GW.selection[i]);
hRequest r; r.v = 0;
@ -592,14 +592,14 @@ void GraphicsWindow::MenuEdit(int id) {
r = s->entity.request();
}
if(r.v && !r.IsFromReferences()) {
SS.request.Tag(r, 1);
SK.request.Tag(r, 1);
}
if(s->constraint.v) {
SS.constraint.Tag(s->constraint, 1);
SK.constraint.Tag(s->constraint, 1);
}
}
SS.constraint.RemoveTagged();
SK.constraint.RemoveTagged();
SS.GW.DeleteTaggedRequests();
break;
}
@ -627,7 +627,7 @@ void GraphicsWindow::MenuRequest(int id) {
switch(id) {
case MNU_SEL_WORKPLANE: {
SS.GW.GroupSelection();
Group *g = SS.GetGroup(SS.GW.activeGroup);
Group *g = SK.GetGroup(SS.GW.activeGroup);
if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) {
// A user-selected workplane
@ -683,7 +683,7 @@ c:
for(i = 0; i < SS.GW.gs.entities; i++) {
hEntity he = SS.GW.gs.entity[i];
if(!he.isFromRequest()) continue;
Request *r = SS.GetRequest(he.request());
Request *r = SK.GetRequest(he.request());
r->construction = !(r->construction);
SS.MarkGroupDirty(r->group);
}

View File

@ -17,7 +17,7 @@ void Group::AddParam(IdList<Param,hParam> *param, hParam hp, double v) {
}
void Group::MenuGroup(int id) {
if(!SS.license.licensed && SS.group.n >= 7) {
if(!SS.license.licensed && SK.group.n >= 7) {
Error("The free version of this software does not support more "
"than six groups.\r\n\r\n"
"To remove this restriction, please choose Help -> "
@ -63,8 +63,8 @@ void Group::MenuGroup(int id) {
g.predef.entityB = gs.entity[0];
g.predef.entityC = gs.entity[1];
Vector ut = SS.GetEntity(g.predef.entityB)->VectorGetNum();
Vector vt = SS.GetEntity(g.predef.entityC)->VectorGetNum();
Vector ut = SK.GetEntity(g.predef.entityB)->VectorGetNum();
Vector vt = SK.GetEntity(g.predef.entityC)->VectorGetNum();
ut = ut.WithMagnitude(1);
vt = vt.WithMagnitude(1);
@ -98,7 +98,7 @@ void Group::MenuGroup(int id) {
g.predef.origin = gs.point[0];
g.predef.entityB = gs.vector[0];
} else if(gs.lineSegments == 1 && gs.n == 1) {
g.predef.origin = SS.GetEntity(gs.entity[0])->point[0];
g.predef.origin = SK.GetEntity(gs.entity[0])->point[0];
g.predef.entityB = gs.entity[0];
// since a line segment is a vector
} else {
@ -120,14 +120,14 @@ void Group::MenuGroup(int id) {
// Get the group one before the active group; that's our
// trajectory
int i;
for(i = 1; i < SS.group.n - 1; i++) {
Group *gnext = &(SS.group.elem[i+1]);
for(i = 1; i < SK.group.n - 1; i++) {
Group *gnext = &(SK.group.elem[i+1]);
if(gnext->h.v == SS.GW.activeGroup.v) {
g.opA = SS.group.elem[i].h;
g.opA = SK.group.elem[i].h;
break;
}
}
if(i >= SS.group.n - 1) {
if(i >= SK.group.n - 1) {
Error("At least one sketch before the active sketch must "
"exist; that specifies the sweep trajectory.");
return;
@ -140,10 +140,10 @@ void Group::MenuGroup(int id) {
case GraphicsWindow::MNU_GROUP_HELICAL: {
if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) {
Vector pt = SS.GetEntity(gs.point[0])->PointGetNum();
Entity *ln = SS.GetEntity(gs.entity[0]);
Vector lpa = SS.GetEntity(ln->point[0])->PointGetNum();
Vector lpb = SS.GetEntity(ln->point[1])->PointGetNum();
Vector pt = SK.GetEntity(gs.point[0])->PointGetNum();
Entity *ln = SK.GetEntity(gs.entity[0]);
Vector lpa = SK.GetEntity(ln->point[0])->PointGetNum();
Vector lpb = SK.GetEntity(ln->point[1])->PointGetNum();
double d = pt.DistanceToLine(lpa, lpb.Minus(lpa));
if(d < LENGTH_EPS) {
Error("Point on helix can't lie on helix's axis!");
@ -171,7 +171,7 @@ void Group::MenuGroup(int id) {
case GraphicsWindow::MNU_GROUP_ROT: {
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
g.predef.origin = gs.point[0];
Entity *w = SS.GetEntity(SS.GW.ActiveWorkplane());
Entity *w = SK.GetEntity(SS.GW.ActiveWorkplane());
g.predef.entityB = w->Normal()->h;
g.activeWorkplane = w->h;
} else if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) {
@ -220,8 +220,8 @@ void Group::MenuGroup(int id) {
SS.GW.ClearSelection();
SS.UndoRemember();
SS.group.AddAndAssignId(&g);
Group *gg = SS.GetGroup(g.h);
SK.group.AddAndAssignId(&g);
Group *gg = SK.GetGroup(g.h);
if(gg->type == IMPORTED) {
SS.ReloadAllImported();
@ -277,8 +277,8 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
case DRAWING_WORKPLANE: {
Quaternion q;
if(subtype == WORKPLANE_BY_LINE_SEGMENTS) {
Vector u = SS.GetEntity(predef.entityB)->VectorGetNum();
Vector v = SS.GetEntity(predef.entityC)->VectorGetNum();
Vector u = SK.GetEntity(predef.entityB)->VectorGetNum();
Vector v = SK.GetEntity(predef.entityC)->VectorGetNum();
u = u.WithMagnitude(1);
Vector n = u.Cross(v);
v = (n.Cross(u)).WithMagnitude(1);
@ -304,7 +304,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
Entity point;
memset(&point, 0, sizeof(point));
point.type = Entity::POINT_N_COPY;
point.numPoint = SS.GetEntity(predef.origin)->PointGetNum();
point.numPoint = SK.GetEntity(predef.origin)->PointGetNum();
point.group = h;
point.h = h.entity(2);
entity->Add(&point);
@ -344,11 +344,11 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
hEntity he = e->h; e = NULL;
// As soon as I call CopyEntity, e may become invalid! That
// adds entities, which may cause a realloc.
CopyEntity(entity, SS.GetEntity(he), ai, REMAP_BOTTOM,
CopyEntity(entity, SK.GetEntity(he), ai, REMAP_BOTTOM,
h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true, false);
CopyEntity(entity, SS.GetEntity(he), af, REMAP_TOP,
CopyEntity(entity, SK.GetEntity(he), af, REMAP_TOP,
h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true, false);
@ -477,12 +477,12 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
// The axis and center of rotation are specified numerically
#define EC(x) (Expr::From(x))
#define EP(x) (Expr::From(h.param(x)))
ExprVector orig = SS.GetEntity(predef.origin)->PointGetExprs();
ExprVector orig = SK.GetEntity(predef.origin)->PointGetExprs();
AddEq(l, (orig.x)->Minus(EP(0)), 0);
AddEq(l, (orig.y)->Minus(EP(1)), 1);
AddEq(l, (orig.z)->Minus(EP(2)), 2);
// param 3 is the angle, which is free
Vector axis = SS.GetEntity(predef.entityB)->VectorGetNum();
Vector axis = SK.GetEntity(predef.entityB)->VectorGetNum();
axis = axis.WithMagnitude(1);
AddEq(l, (EC(axis.x))->Minus(EP(4)), 3);
AddEq(l, (EC(axis.y))->Minus(EP(5)), 4);
@ -491,7 +491,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) {
// The extrusion path is locked along a line, normal to the
// specified workplane.
Entity *w = SS.GetEntity(predef.entityB);
Entity *w = SK.GetEntity(predef.entityB);
ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV();
ExprVector extruden = {
@ -504,7 +504,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
}
} else if(type == TRANSLATE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) {
Entity *w = SS.GetEntity(predef.entityB);
Entity *w = SK.GetEntity(predef.entityB);
ExprVector n = w->Normal()->NormalExprsN();
ExprVector trans;
trans = ExprVector::From(h.param(0), h.param(1), h.param(2));
@ -543,7 +543,7 @@ hEntity Group::Remap(hEntity in, int copyNumber) {
}
void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
Entity *ep = SS.GetEntity(in);
Entity *ep = SK.GetEntity(in);
Entity en;
ZERO(&en);
@ -558,8 +558,8 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
} else if(ep->type == Entity::LINE_SEGMENT) {
// A line gets extruded to form a plane face; an endpoint of the
// original line is a point in the plane, and the line is in the plane.
Vector a = SS.GetEntity(ep->point[0])->PointGetNum();
Vector b = SS.GetEntity(ep->point[1])->PointGetNum();
Vector a = SK.GetEntity(ep->point[0])->PointGetNum();
Vector b = SK.GetEntity(ep->point[1])->PointGetNum();
Vector ab = b.Minus(a);
en.param[0] = h.param(0);
@ -578,7 +578,7 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
{
if(pt.v == 0) return;
Group *src = SS.GetGroup(opA);
Group *src = SK.GetGroup(opA);
Vector n = src->poly.normal;
Entity en;
@ -742,13 +742,13 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
void Group::TagEdgesFromLineSegments(SEdgeList *el) {
int i, j;
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(e->group.v != opA.v) continue;
if(e->type != Entity::LINE_SEGMENT) continue;
Vector p0 = SS.GetEntity(e->point[0])->PointGetNum();
Vector p1 = SS.GetEntity(e->point[1])->PointGetNum();
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
Vector p1 = SK.GetEntity(e->point[1])->PointGetNum();
for(j = 0; j < el->l.n; j++) {
SEdge *se = &(el->l.elem[j]);

View File

@ -7,8 +7,8 @@ bool Group::AssembleLoops(void) {
ZERO(&sbl);
int i;
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(e->group.v != h.v) continue;
if(e->construction) continue;
@ -52,7 +52,7 @@ void Group::GenerateLoops(void) {
}
void Group::GenerateShellForStepAndRepeat(void) {
Group *src = SS.GetGroup(opA);
Group *src = SK.GetGroup(opA);
SShell *srcs = &(src->thisShell); // the shell to step and repeat
SShell workA, workB;
@ -79,7 +79,7 @@ void Group::GenerateShellForStepAndRepeat(void) {
transd.MakeFromTransformationOf(srcs, trans, q);
} else {
Vector trans = Vector::From(h.param(0), h.param(1), h.param(2));
double theta = ap * SS.GetParam(h.param(3))->val;
double theta = ap * SK.GetParam(h.param(3))->val;
double c = cos(theta), s = sin(theta);
Vector axis = Vector::From(h.param(4), h.param(5), h.param(6));
Quaternion q = Quaternion::From(c, s*axis.x, s*axis.y, s*axis.z);
@ -122,7 +122,7 @@ void Group::GenerateShellAndMesh(void) {
}
if(type == EXTRUDE) {
Group *src = SS.GetGroup(opA);
Group *src = SK.GetGroup(opA);
Vector translate = Vector::From(h.param(0), h.param(1), h.param(2));
Vector tbot, ttop;
@ -162,12 +162,12 @@ void Group::GenerateShellAndMesh(void) {
if(ss->degm != 1 || ss->degn != 1) continue;
Entity *e;
for(e = SS.entity.First(); e; e = SS.entity.NextAfter(e)) {
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
if(e->group.v != opA.v) continue;
if(e->type != Entity::LINE_SEGMENT) continue;
Vector a = SS.GetEntity(e->point[0])->PointGetNum(),
b = SS.GetEntity(e->point[1])->PointGetNum();
Vector a = SK.GetEntity(e->point[0])->PointGetNum(),
b = SK.GetEntity(e->point[1])->PointGetNum();
a = a.Plus(ttop);
b = b.Plus(ttop);
// Could get taken backwards, so check all cases.
@ -183,24 +183,24 @@ void Group::GenerateShellAndMesh(void) {
}
}
} else if(type == LATHE) {
Group *src = SS.GetGroup(opA);
Group *src = SK.GetGroup(opA);
Vector orig = SS.GetEntity(predef.origin)->PointGetNum();
Vector axis = SS.GetEntity(predef.entityB)->VectorGetNum();
Vector orig = SK.GetEntity(predef.origin)->PointGetNum();
Vector axis = SK.GetEntity(predef.entityB)->VectorGetNum();
axis = axis.WithMagnitude(1);
} else if(type == IMPORTED) {
// Triangles are just copied over, with the appropriate transformation
// applied.
Vector offset = {
SS.GetParam(h.param(0))->val,
SS.GetParam(h.param(1))->val,
SS.GetParam(h.param(2))->val };
SK.GetParam(h.param(0))->val,
SK.GetParam(h.param(1))->val,
SK.GetParam(h.param(2))->val };
Quaternion q = {
SS.GetParam(h.param(3))->val,
SS.GetParam(h.param(4))->val,
SS.GetParam(h.param(5))->val,
SS.GetParam(h.param(6))->val };
SK.GetParam(h.param(3))->val,
SK.GetParam(h.param(4))->val,
SK.GetParam(h.param(5))->val,
SK.GetParam(h.param(6))->val };
for(int i = 0; i < impMesh.l.n; i++) {
STriangle st = impMesh.l.elem[i];
@ -245,12 +245,12 @@ done:
SShell *Group::PreviousGroupShell(void) {
int i;
for(i = 0; i < SS.group.n; i++) {
Group *g = &(SS.group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
if(g->h.v == h.v) break;
}
if(i == 0 || i >= SS.group.n) oops();
return &(SS.group.elem[i-1].runningShell);
if(i == 0 || i >= SK.group.n) oops();
return &(SK.group.elem[i-1].runningShell);
}
void Group::Draw(void) {
@ -272,7 +272,7 @@ void Group::Draw(void) {
// or hovered, in order to draw them differently.
DWORD mh = 0, ms1 = 0, ms2 = 0;
hEntity he = SS.GW.hover.entity;
if(he.v != 0 && SS.GetEntity(he)->IsFace()) {
if(he.v != 0 && SK.GetEntity(he)->IsFace()) {
mh = he.v;
}
SS.GW.GroupSelection();

View File

@ -6,8 +6,8 @@
//-----------------------------------------------------------------------------
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
int i;
for(i = 0; i < SS.constraint.n; i++) {
Constraint *c = &(SS.constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->type == Constraint::POINTS_COINCIDENT) {
if(c->ptA.v == oldpt.v) c->ptA = newpt;
@ -31,22 +31,22 @@ void GraphicsWindow::MakeTangentArc(void) {
// Find two line segments that join at the specified point,
// and blend them with a tangent arc. First, find the
// requests that generate the line segments.
Vector pshared = SS.GetEntity(gs.point[0])->PointGetNum();
Vector pshared = SK.GetEntity(gs.point[0])->PointGetNum();
ClearSelection();
int i, c = 0;
Entity *line[2];
Request *lineReq[2];
bool point1[2];
for(i = 0; i < SS.request.n; i++) {
Request *r = &(SS.request.elem[i]);
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(r->group.v != activeGroup.v) continue;
if(r->type != Request::LINE_SEGMENT) continue;
if(r->construction) continue;
Entity *e = SS.GetEntity(r->h.entity(0));
Vector p0 = SS.GetEntity(e->point[0])->PointGetNum(),
p1 = SS.GetEntity(e->point[1])->PointGetNum();
Entity *e = SK.GetEntity(r->h.entity(0));
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum(),
p1 = SK.GetEntity(e->point[1])->PointGetNum();
if(p0.Equals(pshared) || p1.Equals(pshared)) {
if(c < 2) {
@ -65,15 +65,15 @@ void GraphicsWindow::MakeTangentArc(void) {
SS.UndoRemember();
Entity *wrkpl = SS.GetEntity(ActiveWorkplane());
Entity *wrkpl = SK.GetEntity(ActiveWorkplane());
Vector wn = wrkpl->Normal()->NormalN();
hEntity hshared = (line[0])->point[point1[0] ? 1 : 0],
hother0 = (line[0])->point[point1[0] ? 0 : 1],
hother1 = (line[1])->point[point1[1] ? 0 : 1];
Vector pother0 = SS.GetEntity(hother0)->PointGetNum(),
pother1 = SS.GetEntity(hother1)->PointGetNum();
Vector pother0 = SK.GetEntity(hother0)->PointGetNum(),
pother1 = SK.GetEntity(hother1)->PointGetNum();
Vector v0shared = pshared.Minus(pother0),
v1shared = pshared.Minus(pother1);
@ -109,21 +109,21 @@ void GraphicsWindow::MakeTangentArc(void) {
rln1 = AddRequest(Request::LINE_SEGMENT, false);
hRequest rarc = AddRequest(Request::ARC_OF_CIRCLE, false);
Entity *ln0 = SS.GetEntity(rln0.entity(0)),
*ln1 = SS.GetEntity(rln1.entity(0));
Entity *arc = SS.GetEntity(rarc.entity(0));
Entity *ln0 = SK.GetEntity(rln0.entity(0)),
*ln1 = SK.GetEntity(rln1.entity(0));
Entity *arc = SK.GetEntity(rarc.entity(0));
SS.GetEntity(ln0->point[0])->PointForceTo(pother0);
SK.GetEntity(ln0->point[0])->PointForceTo(pother0);
Constraint::ConstrainCoincident(ln0->point[0], hother0);
SS.GetEntity(ln1->point[0])->PointForceTo(pother1);
SK.GetEntity(ln1->point[0])->PointForceTo(pother1);
Constraint::ConstrainCoincident(ln1->point[0], hother1);
Vector arc0 = pshared.Minus(v0shared.WithMagnitude(el));
Vector arc1 = pshared.Minus(v1shared.WithMagnitude(el));
SS.GetEntity(ln0->point[1])->PointForceTo(arc0);
SS.GetEntity(ln1->point[1])->PointForceTo(arc1);
SK.GetEntity(ln0->point[1])->PointForceTo(arc0);
SK.GetEntity(ln1->point[1])->PointForceTo(arc1);
Constraint::Constrain(Constraint::PT_ON_LINE,
ln0->point[1], Entity::NO_ENTITY, srcline0);
@ -140,9 +140,9 @@ void GraphicsWindow::MakeTangentArc(void) {
center = center.Plus(v0shared.Cross(wn).WithMagnitude(r));
}
SS.GetEntity(arc->point[0])->PointForceTo(center);
SS.GetEntity(arc->point[a])->PointForceTo(arc0);
SS.GetEntity(arc->point[b])->PointForceTo(arc1);
SK.GetEntity(arc->point[0])->PointForceTo(center);
SK.GetEntity(arc->point[a])->PointForceTo(arc0);
SK.GetEntity(arc->point[b])->PointForceTo(arc1);
Constraint::ConstrainCoincident(arc->point[a], ln0->point[1]);
Constraint::ConstrainCoincident(arc->point[b], ln1->point[1]);
@ -159,10 +159,10 @@ void GraphicsWindow::MakeTangentArc(void) {
void GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
// Save the original endpoints, since we're about to delete this entity.
Entity *e01 = SS.GetEntity(he);
Entity *e01 = SK.GetEntity(he);
hEntity hep0 = e01->point[0], hep1 = e01->point[1];
Vector p0 = SS.GetEntity(hep0)->PointGetNum(),
p1 = SS.GetEntity(hep1)->PointGetNum();
Vector p0 = SK.GetEntity(hep0)->PointGetNum(),
p1 = SK.GetEntity(hep1)->PointGetNum();
SS.UndoRemember();
@ -171,22 +171,22 @@ void GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
ri1 = AddRequest(Request::LINE_SEGMENT, false);
// Don't get entities till after adding, realloc issues
Entity *e0i = SS.GetEntity(r0i.entity(0)),
*ei1 = SS.GetEntity(ri1.entity(0));
Entity *e0i = SK.GetEntity(r0i.entity(0)),
*ei1 = SK.GetEntity(ri1.entity(0));
SS.GetEntity(e0i->point[0])->PointForceTo(p0);
SS.GetEntity(e0i->point[1])->PointForceTo(pinter);
SS.GetEntity(ei1->point[0])->PointForceTo(pinter);
SS.GetEntity(ei1->point[1])->PointForceTo(p1);
SK.GetEntity(e0i->point[0])->PointForceTo(p0);
SK.GetEntity(e0i->point[1])->PointForceTo(pinter);
SK.GetEntity(ei1->point[0])->PointForceTo(pinter);
SK.GetEntity(ei1->point[1])->PointForceTo(p1);
ReplacePointInConstraints(hep0, e0i->point[0]);
ReplacePointInConstraints(hep1, ei1->point[1]);
// Finally, delete the original line
int i;
SS.request.ClearTags();
for(i = 0; i < SS.request.n; i++) {
Request *r = &(SS.request.elem[i]);
SK.request.ClearTags();
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(r->group.v != activeGroup.v) continue;
if(r->type != Request::LINE_SEGMENT) continue;
@ -203,46 +203,46 @@ void GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
void GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
SS.UndoRemember();
Entity *circle = SS.GetEntity(he);
Entity *circle = SK.GetEntity(he);
if(circle->type == Entity::CIRCLE) {
// Start with an unbroken circle, split it into a 360 degree arc.
Vector center = SS.GetEntity(circle->point[0])->PointGetNum();
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
circle = NULL; // shortly invalid!
hRequest hr = AddRequest(Request::ARC_OF_CIRCLE, false);
Entity *arc = SS.GetEntity(hr.entity(0));
Entity *arc = SK.GetEntity(hr.entity(0));
SS.GetEntity(arc->point[0])->PointForceTo(center);
SS.GetEntity(arc->point[1])->PointForceTo(pinter);
SS.GetEntity(arc->point[2])->PointForceTo(pinter);
SK.GetEntity(arc->point[0])->PointForceTo(center);
SK.GetEntity(arc->point[1])->PointForceTo(pinter);
SK.GetEntity(arc->point[2])->PointForceTo(pinter);
} else {
// Start with an arc, break it in to two arcs
Vector center = SS.GetEntity(circle->point[0])->PointGetNum(),
start = SS.GetEntity(circle->point[1])->PointGetNum(),
finish = SS.GetEntity(circle->point[2])->PointGetNum();
Vector center = SK.GetEntity(circle->point[0])->PointGetNum(),
start = SK.GetEntity(circle->point[1])->PointGetNum(),
finish = SK.GetEntity(circle->point[2])->PointGetNum();
circle = NULL; // shortly invalid!
hRequest hr0 = AddRequest(Request::ARC_OF_CIRCLE, false),
hr1 = AddRequest(Request::ARC_OF_CIRCLE, false);
Entity *arc0 = SS.GetEntity(hr0.entity(0)),
*arc1 = SS.GetEntity(hr1.entity(0));
Entity *arc0 = SK.GetEntity(hr0.entity(0)),
*arc1 = SK.GetEntity(hr1.entity(0));
SS.GetEntity(arc0->point[0])->PointForceTo(center);
SS.GetEntity(arc0->point[1])->PointForceTo(start);
SS.GetEntity(arc0->point[2])->PointForceTo(pinter);
SK.GetEntity(arc0->point[0])->PointForceTo(center);
SK.GetEntity(arc0->point[1])->PointForceTo(start);
SK.GetEntity(arc0->point[2])->PointForceTo(pinter);
SS.GetEntity(arc1->point[0])->PointForceTo(center);
SS.GetEntity(arc1->point[1])->PointForceTo(pinter);
SS.GetEntity(arc1->point[2])->PointForceTo(finish);
SK.GetEntity(arc1->point[0])->PointForceTo(center);
SK.GetEntity(arc1->point[1])->PointForceTo(pinter);
SK.GetEntity(arc1->point[2])->PointForceTo(finish);
}
// Finally, delete the original circle or arc
int i;
SS.request.ClearTags();
for(i = 0; i < SS.request.n; i++) {
Request *r = &(SS.request.elem[i]);
SK.request.ClearTags();
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(r->group.v != activeGroup.v) continue;
if(r->type != Request::CIRCLE && r->type != Request::ARC_OF_CIRCLE) {
continue;
@ -266,12 +266,12 @@ void GraphicsWindow::SplitLinesOrCurves(void) {
GroupSelection();
if(gs.n == 2 && gs.lineSegments == 2) {
Entity *la = SS.GetEntity(gs.entity[0]),
*lb = SS.GetEntity(gs.entity[1]);
Vector a0 = SS.GetEntity(la->point[0])->PointGetNum(),
a1 = SS.GetEntity(la->point[1])->PointGetNum(),
b0 = SS.GetEntity(lb->point[0])->PointGetNum(),
b1 = SS.GetEntity(lb->point[1])->PointGetNum();
Entity *la = SK.GetEntity(gs.entity[0]),
*lb = SK.GetEntity(gs.entity[1]);
Vector a0 = SK.GetEntity(la->point[0])->PointGetNum(),
a1 = SK.GetEntity(la->point[1])->PointGetNum(),
b0 = SK.GetEntity(lb->point[0])->PointGetNum(),
b1 = SK.GetEntity(lb->point[1])->PointGetNum();
Vector da = a1.Minus(a0), db = b1.Minus(b0);
// First, check if the lines intersect.
@ -306,20 +306,20 @@ void GraphicsWindow::SplitLinesOrCurves(void) {
"Nothing to split; intersection does not lie on either line.");
}
} else if(gs.n == 2 && gs.lineSegments == 1 && gs.circlesOrArcs == 1) {
Entity *line = SS.GetEntity(gs.entity[0]),
*circle = SS.GetEntity(gs.entity[1]);
Entity *line = SK.GetEntity(gs.entity[0]),
*circle = SK.GetEntity(gs.entity[1]);
if(line->type != Entity::LINE_SEGMENT) {
SWAP(Entity *, line, circle);
}
hEntity hline = line->h, hcircle = circle->h;
Vector l0 = SS.GetEntity(line->point[0])->PointGetNum(),
l1 = SS.GetEntity(line->point[1])->PointGetNum();
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector dl = l1.Minus(l0);
Quaternion q = SS.GetEntity(circle->normal)->NormalGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
Vector cn = q.RotationN();
Vector cc = SS.GetEntity(circle->point[0])->PointGetNum();
Vector cc = SK.GetEntity(circle->point[0])->PointGetNum();
double cd = cc.Dot(cn);
double cr = circle->CircleGetRadiusNum();
@ -357,8 +357,8 @@ void GraphicsWindow::SplitLinesOrCurves(void) {
thetamin = 0;
thetamax = 2.1*PI; // fudge, make sure it's a good complete circle
} else {
Vector start = SS.GetEntity(circle->point[1])->PointGetNum(),
finish = SS.GetEntity(circle->point[2])->PointGetNum();
Vector start = SK.GetEntity(circle->point[1])->PointGetNum(),
finish = SK.GetEntity(circle->point[2])->PointGetNum();
start = (start .Minus(cc)).DotInToCsys(u, v, n);
finish = (finish.Minus(cc)).DotInToCsys(u, v, n);
thetamin = atan2(start.y, start.x);

View File

@ -1,6 +1,7 @@
#include "solvespace.h"
SolveSpace SS;
Sketch SK;
void SolveSpace::CheckLicenseFromRegistry(void) {
// First, let's see if we're running licensed or free
@ -388,7 +389,7 @@ void SolveSpace::MenuAnalyze(int id) {
switch(id) {
case GraphicsWindow::MNU_STEP_DIM:
if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SS.GetConstraint(gs.constraint[0]);
Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->HasLabel() && !c->reference) {
SS.TW.shown.dimFinish = c->valA;
SS.TW.shown.dimSteps = 10;
@ -416,7 +417,7 @@ void SolveSpace::MenuAnalyze(int id) {
case GraphicsWindow::MNU_NAKED_EDGES: {
SS.nakedEdges.Clear();
SMesh *m = &(SS.GetGroup(SS.GW.activeGroup)->runningMesh);
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
SKdNode *root = SKdNode::From(m);
bool inters, leaks;
root->MakeNakedEdgesInto(&(SS.nakedEdges), &inters, &leaks);
@ -440,7 +441,7 @@ void SolveSpace::MenuAnalyze(int id) {
}
case GraphicsWindow::MNU_VOLUME: {
SMesh *m = &(SS.GetGroup(SS.GW.activeGroup)->runningMesh);
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->runningMesh);
double vol = 0;
int i;

View File

@ -410,26 +410,29 @@ public:
void FinishAndCloseFile(void);
};
class SolveSpace {
class Sketch {
public:
TextWindow TW;
GraphicsWindow GW;
// These lists define the sketch, and are edited by the user.
// These are user-editable, and define the sketch.
IdList<Group,hGroup> group;
IdList<Request,hRequest> request;
IdList<Constraint,hConstraint> constraint;
IdList<Request,hRequest> request;
// These lists are generated automatically when we solve the sketch.
// These are generated from the above.
IdList<Entity,hEntity> entity;
IdList<Param,hParam> param;
inline Constraint *GetConstraint(hConstraint h)
{ return constraint.FindById(h); }
inline Request *GetRequest(hRequest h) { return request.FindById(h); }
inline Entity *GetEntity (hEntity h) { return entity. FindById(h); }
inline Param *GetParam (hParam h) { return param. FindById(h); }
inline Request *GetRequest(hRequest h) { return request.FindById(h); }
inline Group *GetGroup (hGroup h) { return group. FindById(h); }
};
class SolveSpace {
public:
TextWindow TW;
GraphicsWindow GW;
// The state for undo/redo
typedef struct {
@ -608,5 +611,6 @@ public:
};
extern SolveSpace SS;
extern Sketch SK;
#endif

View File

@ -21,7 +21,7 @@ void System::WriteJacobian(int tag) {
if(e->tag != tag) continue;
mat.eq[i] = e->h;
Expr *f = e->e->DeepCopyWithParamsAsPointers(&param, &(SS.param));
Expr *f = e->e->DeepCopyWithParamsAsPointers(&param, &(SK.param));
f = f->FoldConstants();
// Hash table (61 bits) to accelerate generation of zero partials.
@ -33,7 +33,7 @@ void System::WriteJacobian(int tag) {
{
pd = f->PartialWrt(mat.param[j]);
pd = pd->FoldConstants();
pd = pd->DeepCopyWithParamsAsPointers(&param, &(SS.param));
pd = pd->DeepCopyWithParamsAsPointers(&param, &(SK.param));
} else {
pd = Expr::From(0.0);
}
@ -59,7 +59,7 @@ bool System::IsDragged(hParam p) {
// The pending point could be one in a group that has not yet
// been processed, in which case the lookup will fail; but
// that's not an error.
Entity *pt = SS.entity.FindByIdNoOops(SS.GW.pending.point);
Entity *pt = SK.entity.FindByIdNoOops(SS.GW.pending.point);
if(pt) {
switch(pt->type) {
case Entity::POINT_N_TRANS:
@ -77,9 +77,9 @@ bool System::IsDragged(hParam p) {
}
}
if(SS.GW.pending.circle.v) {
Entity *circ = SS.entity.FindByIdNoOops(SS.GW.pending.circle);
Entity *circ = SK.entity.FindByIdNoOops(SS.GW.pending.circle);
if(circ) {
Entity *dist = SS.GetEntity(circ->distance);
Entity *dist = SK.GetEntity(circ->distance);
switch(dist->type) {
case Entity::DISTANCE:
if(p.v == (dist->param[0].v)) return true;
@ -88,7 +88,7 @@ bool System::IsDragged(hParam p) {
}
}
if(SS.GW.pending.normal.v) {
Entity *norm = SS.entity.FindByIdNoOops(SS.GW.pending.normal);
Entity *norm = SK.entity.FindByIdNoOops(SS.GW.pending.normal);
if(norm) {
switch(norm->type) {
case Entity::NORMAL_IN_3D:
@ -343,22 +343,22 @@ bool System::NewtonSolve(int tag) {
void System::WriteEquationsExceptFor(hConstraint hc, hGroup hg) {
int i;
// Generate all the equations from constraints in this group
for(i = 0; i < SS.constraint.n; i++) {
Constraint *c = &(SS.constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->group.v != hg.v) continue;
if(c->h.v == hc.v) continue;
c->Generate(&eq);
}
// And the equations from entities
for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]);
for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SK.entity.elem[i]);
if(e->group.v != hg.v) continue;
e->GenerateEquations(&eq);
}
// And from the groups themselves
(SS.GetGroup(hg))->GenerateEquations(&eq);
(SK.GetGroup(hg))->GenerateEquations(&eq);
}
void System::FindWhichToRemoveToFixJacobian(Group *g) {
@ -366,8 +366,8 @@ void System::FindWhichToRemoveToFixJacobian(Group *g) {
(g->solved.remove).Clear();
for(a = 0; a < 2; a++) {
for(i = 0; i < SS.constraint.n; i++) {
Constraint *c = &(SS.constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->group.v != g->h.v) continue;
if((c->type == Constraint::POINTS_COINCIDENT && a == 0) ||
(c->type != Constraint::POINTS_COINCIDENT && a == 1))
@ -502,7 +502,7 @@ void System::Solve(Group *g, bool andFindFree) {
} else {
val = p->val;
}
Param *pp = SS.GetParam(p->h);
Param *pp = SK.GetParam(p->h);
pp->val = val;
pp->known = true;
pp->free = p->free;
@ -516,14 +516,14 @@ void System::Solve(Group *g, bool andFindFree) {
didnt_converge:
g->solved.how = Group::DIDNT_CONVERGE;
(g->solved.remove).Clear();
SS.constraint.ClearTags();
SK.constraint.ClearTags();
for(i = 0; i < eq.n; i++) {
if(fabs(mat.B.num[i]) > CONVERGE_TOLERANCE || isnan(mat.B.num[i])) {
// This constraint is unsatisfied.
if(!mat.eq[i].isFromConstraint()) continue;
hConstraint hc = mat.eq[i].constraint();
Constraint *c = SS.constraint.FindByIdNoOops(hc);
Constraint *c = SK.constraint.FindByIdNoOops(hc);
if(!c) continue;
// Don't double-show constraints that generated multiple
// unsatisfied equations

View File

@ -11,7 +11,7 @@ void TextWindow::ShowHeader(bool withNav) {
ClearScreen();
char *cd = SS.GW.LockedInWorkplane() ?
SS.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString() :
SK.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString() :
"free in 3d";
// Navigation buttons
@ -58,7 +58,7 @@ void TextWindow::ScreenSelectGroup(int link, DWORD v) {
}
void TextWindow::ScreenToggleGroupShown(int link, DWORD v) {
hGroup hg = { v };
Group *g = SS.GetGroup(hg);
Group *g = SK.GetGroup(hg);
g->visible = !(g->visible);
// If a group was just shown, then it might not have been generated
// previously, so regenerate.
@ -66,8 +66,8 @@ void TextWindow::ScreenToggleGroupShown(int link, DWORD v) {
}
void TextWindow::ScreenShowGroupsSpecial(int link, DWORD v) {
int i;
for(i = 0; i < SS.group.n; i++) {
Group *g = &(SS.group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
if(link == 's') {
g->visible = true;
@ -78,10 +78,10 @@ void TextWindow::ScreenShowGroupsSpecial(int link, DWORD v) {
}
void TextWindow::ScreenActivateGroup(int link, DWORD v) {
hGroup hg = { v };
Group *g = SS.GetGroup(hg);
Group *g = SK.GetGroup(hg);
g->visible = true;
SS.GW.activeGroup.v = v;
SS.GetGroup(SS.GW.activeGroup)->Activate();
SK.GetGroup(SS.GW.activeGroup)->Activate();
SS.GW.ClearSuper();
}
void TextWindow::ReportHowGroupSolved(hGroup hg) {
@ -107,8 +107,8 @@ void TextWindow::ShowListOfGroups(void) {
Printf(true, "%Ftactv show ok group-name%E");
int i;
bool afterActive = false;
for(i = 0; i < SS.group.n; i++) {
Group *g = &(SS.group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
char *s = g->DescriptionString();
bool active = (g->h.v == SS.GW.activeGroup.v);
bool shown = g->visible;
@ -172,7 +172,7 @@ void TextWindow::ScreenHoverConstraint(int link, DWORD v) {
if(!SS.GW.showConstraints) return;
hConstraint hc = { v };
Constraint *c = SS.GetConstraint(hc);
Constraint *c = SK.GetConstraint(hc);
if(c->group.v != SS.GW.activeGroup.v) {
// Only constraints in the active group are visible
return;
@ -199,7 +199,7 @@ void TextWindow::ScreenSelectRequest(int link, DWORD v) {
void TextWindow::ScreenChangeOneOrTwoSides(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
if(g->subtype == Group::ONE_SIDED) {
g->subtype = Group::TWO_SIDED;
} else if(g->subtype == Group::TWO_SIDED) {
@ -212,7 +212,7 @@ void TextWindow::ScreenChangeOneOrTwoSides(int link, DWORD v) {
void TextWindow::ScreenChangeSkipFirst(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
(g->skipFirst) = !(g->skipFirst);
SS.MarkGroupDirty(g->h);
SS.GenerateAll();
@ -221,7 +221,7 @@ void TextWindow::ScreenChangeSkipFirst(int link, DWORD v) {
void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
g->meshCombine = v;
SS.MarkGroupDirty(g->h);
SS.GenerateAll();
@ -230,7 +230,7 @@ void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
void TextWindow::ScreenChangeSuppress(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
g->suppress = !(g->suppress);
SS.MarkGroupDirty(g->h);
SS.GenerateAll();
@ -239,7 +239,7 @@ void TextWindow::ScreenChangeSuppress(int link, DWORD v) {
void TextWindow::ScreenChangeRightLeftHanded(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
if(g->subtype == Group::RIGHT_HANDED) {
g->subtype = Group::LEFT_HANDED;
} else {
@ -250,7 +250,7 @@ void TextWindow::ScreenChangeRightLeftHanded(int link, DWORD v) {
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeHelixParameter(int link, DWORD v) {
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
char str[1024];
int r;
if(link == 't') {
@ -272,7 +272,7 @@ void TextWindow::ScreenChangeHelixParameter(int link, DWORD v) {
void TextWindow::ScreenColor(int link, DWORD v) {
SS.UndoRemember();
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
if(v < 0 || v >= SS.MODEL_COLORS) return;
g->color = SS.modelColor[v];
SS.MarkGroupDirty(g->h);
@ -280,7 +280,7 @@ void TextWindow::ScreenColor(int link, DWORD v) {
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeExprA(int link, DWORD v) {
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
// There's an extra line for the skipFirst parameter in one-sided groups.
int r = (g->subtype == Group::ONE_SIDED) ? 15 : 13;
@ -292,7 +292,7 @@ void TextWindow::ScreenChangeExprA(int link, DWORD v) {
SS.TW.edit.group.v = v;
}
void TextWindow::ScreenChangeGroupName(int link, DWORD v) {
Group *g = SS.GetGroup(SS.TW.shown.group);
Group *g = SK.GetGroup(SS.TW.shown.group);
ShowTextEditControl(7, 14, g->DescriptionString()+5);
SS.TW.edit.meaning = EDIT_GROUP_NAME;
SS.TW.edit.group.v = v;
@ -306,14 +306,14 @@ void TextWindow::ScreenDeleteGroup(int link, DWORD v) {
"before proceeding.");
return;
}
SS.group.RemoveById(SS.TW.shown.group);
SK.group.RemoveById(SS.TW.shown.group);
// This is a major change, so let's re-solve everything.
SS.TW.ClearSuper();
SS.GW.ClearSuper();
SS.GenerateAll(0, INT_MAX);
}
void TextWindow::ShowGroupInfo(void) {
Group *g = SS.group.FindById(shown.group);
Group *g = SK.group.FindById(shown.group);
char *s, *s2, *s3;
if(shown.group.v == Group::HGROUP_REFERENCES.v) {
@ -459,8 +459,8 @@ void TextWindow::ShowGroupInfo(void) {
}
int i, a = 0;
for(i = 0; i < SS.request.n; i++) {
Request *r = &(SS.request.elem[i]);
for(i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);
if(r->group.v == shown.group.v) {
char *s = r->DescriptionString();
@ -475,8 +475,8 @@ void TextWindow::ShowGroupInfo(void) {
a = 0;
Printf(true, "%Ftconstraints in group (%d DOF)", g->solved.dof);
for(i = 0; i < SS.constraint.n; i++) {
Constraint *c = &(SS.constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *c = &(SK.constraint.elem[i]);
if(c->group.v == shown.group.v) {
char *s = c->DescriptionString();
@ -497,7 +497,7 @@ void TextWindow::ShowGroupInfo(void) {
// constraints that could be removed to fix it.
//-----------------------------------------------------------------------------
void TextWindow::ShowGroupSolveInfo(void) {
Group *g = SS.group.FindById(shown.group);
Group *g = SK.group.FindById(shown.group);
if(g->solved.how == Group::SOLVED_OKAY) {
// Go back to the default group info screen
shown.screen = SCREEN_GROUP_INFO;
@ -520,7 +520,7 @@ void TextWindow::ShowGroupSolveInfo(void) {
for(int i = 0; i < g->solved.remove.n; i++) {
hConstraint hc = g->solved.remove.elem[i];
Constraint *c = SS.constraint.FindByIdNoOops(hc);
Constraint *c = SK.constraint.FindByIdNoOops(hc);
if(!c) continue;
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E",
@ -650,7 +650,7 @@ void TextWindow::ShowConfiguration(void) {
Printf(false, "%Ba %2 %Fl%Ll%f%D[change]%E; now %d triangles",
SS.chordTol,
&ScreenChangeChordTolerance, 0,
SS.GetGroup(SS.GW.activeGroup)->runningMesh.l.n);
SK.GetGroup(SS.GW.activeGroup)->runningMesh.l.n);
Printf(false, "%Ft max piecewise linear segments%E");
Printf(false, "%Ba %d %Fl%Ll%f[change]%E",
SS.maxSegments,
@ -732,13 +732,13 @@ void TextWindow::ScreenStepDimSteps(int link, DWORD v) {
}
void TextWindow::ScreenStepDimGo(int link, DWORD v) {
hConstraint hc = SS.TW.shown.constraint;
Constraint *c = SS.constraint.FindByIdNoOops(hc);
Constraint *c = SK.constraint.FindByIdNoOops(hc);
if(c) {
SS.UndoRemember();
double start = c->valA, finish = SS.TW.shown.dimFinish;
int i, n = SS.TW.shown.dimSteps;
for(i = 1; i <= n; i++) {
c = SS.GetConstraint(hc);
c = SK.GetConstraint(hc);
c->valA = start + ((finish - start)*i)/n;
SS.MarkGroupDirty(c->group);
SS.GenerateAll();
@ -753,7 +753,7 @@ void TextWindow::ScreenStepDimGo(int link, DWORD v) {
SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS);
}
void TextWindow::ShowStepDimension(void) {
Constraint *c = SS.constraint.FindByIdNoOops(shown.constraint);
Constraint *c = SK.constraint.FindByIdNoOops(shown.constraint);
if(!c) {
shown.screen = SCREEN_LIST_OF_GROUPS;
Show();
@ -812,13 +812,13 @@ void TextWindow::EditControlDone(char *s) {
break;
}
Group *g = SS.GetGroup(edit.group);
Group *g = SK.GetGroup(edit.group);
g->valA = ev;
if(g->type == Group::ROTATE) {
int i, c = 0;
for(i = 0; i < SS.constraint.n; i++) {
if(SS.constraint.elem[i].group.v == g->h.v) c++;
for(i = 0; i < SK.constraint.n; i++) {
if(SK.constraint.elem[i].group.v == g->h.v) c++;
}
// If the group does not contain any constraints, then
// set the numerical guess to space the copies uniformly
@ -826,7 +826,7 @@ void TextWindow::EditControlDone(char *s) {
// already constrained, because that would break
// convergence.
if(c == 0) {
SS.GetParam(g->h.param(3))->val = PI/(2*ev);
SK.GetParam(g->h.param(3))->val = PI/(2*ev);
}
}
@ -850,7 +850,7 @@ void TextWindow::EditControlDone(char *s) {
} else {
SS.UndoRemember();
Group *g = SS.GetGroup(edit.group);
Group *g = SK.GetGroup(edit.group);
g->name.strcpy(s);
}
SS.unsaved = true;
@ -936,7 +936,7 @@ void TextWindow::EditControlDone(char *s) {
case EDIT_HELIX_PITCH:
case EDIT_HELIX_DRADIUS: {
SS.UndoRemember();
Group *g = SS.GetGroup(edit.group);
Group *g = SK.GetGroup(edit.group);
Expr *e = Expr::From(s);
if(!e) {
Error("Not a valid number or expression: '%s'", s);
@ -955,7 +955,7 @@ void TextWindow::EditControlDone(char *s) {
}
case EDIT_TTF_TEXT: {
SS.UndoRemember();
Request *r = SS.request.FindByIdNoOops(edit.request);
Request *r = SK.request.FindByIdNoOops(edit.request);
if(r) {
r->str.strcpy(s);
SS.MarkGroupDirty(r->group);

View File

@ -236,7 +236,7 @@ void TextWindow::ScreenUnselectAll(int link, DWORD v) {
void TextWindow::ScreenEditTtfText(int link, DWORD v) {
hRequest hr = { v };
Request *r = SS.GetRequest(hr);
Request *r = SK.GetRequest(hr);
ShowTextEditControl(13, 10, r->str.str);
SS.TW.edit.meaning = EDIT_TTF_TEXT;
@ -251,10 +251,10 @@ void TextWindow::ScreenSetTtfFont(int link, DWORD v) {
SS.GW.GroupSelection();
if(gs.entities != 1 || gs.n != 1) return;
Entity *e = SS.entity.FindByIdNoOops(gs.entity[0]);
Entity *e = SK.entity.FindByIdNoOops(gs.entity[0]);
if(!e || e->type != Entity::TTF_TEXT || !e->h.isFromRequest()) return;
Request *r = SS.request.FindByIdNoOops(e->h.request());
Request *r = SK.request.FindByIdNoOops(e->h.request());
if(!r) return;
SS.UndoRemember();
@ -271,7 +271,7 @@ void TextWindow::DescribeSelection(void) {
Printf(false, "");
if(gs.n == 1 && (gs.points == 1 || gs.entities == 1)) {
e = SS.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]);
e = SK.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]);
#define COSTR(p) \
SS.MmToString((p).x), SS.MmToString((p).y), SS.MmToString((p).z)
@ -304,7 +304,7 @@ void TextWindow::DescribeSelection(void) {
break;
}
case Entity::WORKPLANE: {
p = SS.GetEntity(e->point[0])->PointGetNum();
p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(false, "%FtWORKPLANE%E");
Printf(true, " origin = " PT_AS_STR, COSTR(p));
Quaternion q = e->Normal()->NormalGetNum();
@ -313,11 +313,11 @@ void TextWindow::DescribeSelection(void) {
break;
}
case Entity::LINE_SEGMENT: {
Vector p0 = SS.GetEntity(e->point[0])->PointGetNum();
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
p = p0;
Printf(false, "%FtLINE SEGMENT%E");
Printf(true, " thru " PT_AS_STR, COSTR(p));
Vector p1 = SS.GetEntity(e->point[1])->PointGetNum();
Vector p1 = SK.GetEntity(e->point[1])->PointGetNum();
p = p1;
Printf(false, " " PT_AS_STR, COSTR(p));
Printf(true, " len = %Fi%s%E",
@ -327,18 +327,18 @@ void TextWindow::DescribeSelection(void) {
case Entity::CUBIC:
Printf(false, "%FtCUBIC BEZIER CURVE%E");
for(i = 0; i <= 3; i++) {
p = SS.GetEntity(e->point[i])->PointGetNum();
p = SK.GetEntity(e->point[i])->PointGetNum();
Printf((i==0), " p%c = " PT_AS_STR, '0'+i, COSTR(p));
}
break;
case Entity::ARC_OF_CIRCLE: {
Printf(false, "%FtARC OF A CIRCLE%E");
p = SS.GetEntity(e->point[0])->PointGetNum();
p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(true, " center = " PT_AS_STR, COSTR(p));
p = SS.GetEntity(e->point[1])->PointGetNum();
p = SK.GetEntity(e->point[1])->PointGetNum();
Printf(true, " endpoints = " PT_AS_STR, COSTR(p));
p = SS.GetEntity(e->point[2])->PointGetNum();
p = SK.GetEntity(e->point[2])->PointGetNum();
Printf(false, " " PT_AS_STR, COSTR(p));
double r = e->CircleGetRadiusNum();
Printf(true, " diameter = %Fi%s", SS.MmToString(r*2));
@ -350,7 +350,7 @@ void TextWindow::DescribeSelection(void) {
}
case Entity::CIRCLE: {
Printf(false, "%FtCIRCLE%E");
p = SS.GetEntity(e->point[0])->PointGetNum();
p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(true, " center = " PT_AS_STR, COSTR(p));
double r = e->CircleGetRadiusNum();
Printf(true, " diameter = %Fi%s", SS.MmToString(r*2));
@ -403,40 +403,40 @@ void TextWindow::DescribeSelection(void) {
break;
}
Group *g = SS.GetGroup(e->group);
Group *g = SK.GetGroup(e->group);
Printf(false, "");
Printf(false, "%FtIN GROUP%E %s", g->DescriptionString());
if(e->workplane.v == Entity::FREE_IN_3D.v) {
Printf(false, "%FtNOT LOCKED IN WORKPLANE%E");
} else {
Entity *w = SS.GetEntity(e->workplane);
Entity *w = SK.GetEntity(e->workplane);
Printf(false, "%FtIN WORKPLANE%E %s", w->DescriptionString());
}
} else if(gs.n == 2 && gs.points == 2) {
Printf(false, "%FtTWO POINTS");
Vector p0 = SS.GetEntity(gs.point[0])->PointGetNum();
Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum();
Printf(true, " at " PT_AS_STR, COSTR(p0));
Vector p1 = SS.GetEntity(gs.point[1])->PointGetNum();
Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum();
Printf(false, " " PT_AS_STR, COSTR(p1));
double d = (p1.Minus(p0)).Magnitude();
Printf(true, " d = %Fi%s", SS.MmToString(d));
} else if(gs.n == 2 && gs.faces == 1 && gs.points == 1) {
Printf(false, "%FtA POINT AND A PLANE FACE");
Vector pt = SS.GetEntity(gs.point[0])->PointGetNum();
Vector pt = SK.GetEntity(gs.point[0])->PointGetNum();
Printf(true, " point = " PT_AS_STR, COSTR(pt));
Vector n = SS.GetEntity(gs.face[0])->FaceGetNormalNum();
Vector n = SK.GetEntity(gs.face[0])->FaceGetNormalNum();
Printf(true, " plane normal = " PT_AS_NUM, CO(n));
Vector pl = SS.GetEntity(gs.face[0])->FaceGetPointNum();
Vector pl = SK.GetEntity(gs.face[0])->FaceGetPointNum();
Printf(false, " plane thru = " PT_AS_STR, COSTR(pl));
double dd = n.Dot(pl) - n.Dot(pt);
Printf(true, " distance = %Fi%s", SS.MmToString(dd));
} else if(gs.n == 3 && gs.points == 2 && gs.vectors == 1) {
Printf(false, "%FtTWO POINTS AND A VECTOR");
Vector p0 = SS.GetEntity(gs.point[0])->PointGetNum();
Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum();
Printf(true, " pointA = " PT_AS_STR, COSTR(p0));
Vector p1 = SS.GetEntity(gs.point[1])->PointGetNum();
Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum();
Printf(false, " pointB = " PT_AS_STR, COSTR(p1));
Vector v = SS.GetEntity(gs.vector[0])->VectorGetNum();
Vector v = SK.GetEntity(gs.vector[0])->VectorGetNum();
v = v.WithMagnitude(1);
Printf(true, " vector = " PT_AS_NUM, CO(v));
double d = (p1.Minus(p0)).Dot(v);
@ -444,14 +444,14 @@ void TextWindow::DescribeSelection(void) {
} else if(gs.n == 2 && gs.faces == 2) {
Printf(false, "%FtTWO PLANE FACES");
Vector n0 = SS.GetEntity(gs.face[0])->FaceGetNormalNum();
Vector n0 = SK.GetEntity(gs.face[0])->FaceGetNormalNum();
Printf(true, " planeA normal = " PT_AS_NUM, CO(n0));
Vector p0 = SS.GetEntity(gs.face[0])->FaceGetPointNum();
Vector p0 = SK.GetEntity(gs.face[0])->FaceGetPointNum();
Printf(false, " planeA thru = " PT_AS_STR, COSTR(p0));
Vector n1 = SS.GetEntity(gs.face[1])->FaceGetNormalNum();
Vector n1 = SK.GetEntity(gs.face[1])->FaceGetNormalNum();
Printf(true, " planeB normal = " PT_AS_NUM, CO(n1));
Vector p1 = SS.GetEntity(gs.face[1])->FaceGetPointNum();
Vector p1 = SK.GetEntity(gs.face[1])->FaceGetPointNum();
Printf(false, " planeB thru = " PT_AS_STR, COSTR(p1));
double theta = acos(n0.Dot(n1));

View File

@ -40,8 +40,8 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
UndoState *ut = &(uk->d[uk->write]);
ZERO(ut);
for(i = 0; i < group.n; i++) {
Group *src = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *src = &(SK.group.elem[i]);
Group dest = *src;
// And then clean up all the stuff that needs to be a deep copy,
// and zero out all the dynamic stuff that will get regenerated.
@ -62,17 +62,17 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
ZERO(&(dest.impEntity));
ut->group.Add(&dest);
}
for(i = 0; i < request.n; i++) {
ut->request.Add(&(request.elem[i]));
for(i = 0; i < SK.request.n; i++) {
ut->request.Add(&(SK.request.elem[i]));
}
for(i = 0; i < constraint.n; i++) {
Constraint *src = &(constraint.elem[i]);
for(i = 0; i < SK.constraint.n; i++) {
Constraint *src = &(SK.constraint.elem[i]);
Constraint dest = *src;
ZERO(&(dest.dogd));
ut->constraint.Add(&dest);
}
for(i = 0; i < param.n; i++) {
ut->param.Add(&(param.elem[i]));
for(i = 0; i < SK.param.n; i++) {
ut->param.Add(&(SK.param.elem[i]));
}
ut->activeGroup = SS.GW.activeGroup;
@ -88,8 +88,8 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
int i;
// Free everything in the main copy of the program before replacing it
for(i = 0; i < group.n; i++) {
Group *g = &(group.elem[i]);
for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]);
g->poly.Clear();
g->bezierLoopSet.Clear();
g->runningMesh.Clear();
@ -100,16 +100,16 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
g->impMesh.Clear();
g->impEntity.Clear();
}
group.Clear();
request.Clear();
constraint.Clear();
param.Clear();
SK.group.Clear();
SK.request.Clear();
SK.constraint.Clear();
SK.param.Clear();
// And then do a shallow copy of the state from the undo list
ut->group.MoveSelfInto(&group);
ut->request.MoveSelfInto(&request);
ut->constraint.MoveSelfInto(&constraint);
ut->param.MoveSelfInto(&param);
ut->group.MoveSelfInto(&(SK.group));
ut->request.MoveSelfInto(&(SK.request));
ut->constraint.MoveSelfInto(&(SK.constraint));
ut->param.MoveSelfInto(&(SK.param));
SS.GW.activeGroup = ut->activeGroup;
// No need to free it, since a shallow copy was made above

View File

@ -113,10 +113,10 @@ Quaternion Quaternion::From(double w, double vx, double vy, double vz) {
Quaternion Quaternion::From(hParam w, hParam vx, hParam vy, hParam vz) {
Quaternion q;
q.w = SS.GetParam(w )->val;
q.vx = SS.GetParam(vx)->val;
q.vy = SS.GetParam(vy)->val;
q.vz = SS.GetParam(vz)->val;
q.w = SK.GetParam(w )->val;
q.vx = SK.GetParam(vx)->val;
q.vy = SK.GetParam(vy)->val;
q.vz = SK.GetParam(vz)->val;
return q;
}
@ -277,9 +277,9 @@ Vector Vector::From(double x, double y, double z) {
Vector Vector::From(hParam x, hParam y, hParam z) {
Vector v;
v.x = SS.GetParam(x)->val;
v.y = SS.GetParam(y)->val;
v.z = SS.GetParam(z)->val;
v.x = SK.GetParam(x)->val;
v.y = SK.GetParam(y)->val;
v.z = SK.GetParam(z)->val;
return v;
}
@ -504,7 +504,7 @@ Vector Vector::WithMagnitude(double v) {
}
Vector Vector::ProjectVectorInto(hEntity wrkpl) {
Entity *w = SS.GetEntity(wrkpl);
Entity *w = SK.GetEntity(wrkpl);
Vector u = w->Normal()->NormalU();
Vector v = w->Normal()->NormalV();
@ -515,7 +515,7 @@ Vector Vector::ProjectVectorInto(hEntity wrkpl) {
}
Vector Vector::ProjectInto(hEntity wrkpl) {
Entity *w = SS.GetEntity(wrkpl);
Entity *w = SK.GetEntity(wrkpl);
Vector p0 = w->WorkplaneGetOffset();
Vector f = this->Minus(p0);