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 all: $(OBJDIR)/solvespace.exe
@cp $(OBJDIR)/solvespace.exe . @cp $(OBJDIR)/solvespace.exe .
solvespace t7.slvs solvespace alext.slvs
clean: clean:
rm -f obj/* rm -f obj/*

View File

@ -49,16 +49,16 @@ char *Constraint::DescriptionString(void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Constraint::DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA) void Constraint::DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA)
{ {
SS.constraint.ClearTags(); SK.constraint.ClearTags();
for(int i = 0; i < SS.constraint.n; i++) { for(int i = 0; i < SK.constraint.n; i++) {
Constraint *ct = &(SS.constraint.elem[i]); Constraint *ct = &(SK.constraint.elem[i]);
if(ct->type != type) continue; if(ct->type != type) continue;
if(ct->entityA.v != entityA.v) continue; if(ct->entityA.v != entityA.v) continue;
if(ct->ptA.v != ptA.v) continue; if(ct->ptA.v != ptA.v) continue;
ct->tag = 1; ct->tag = 1;
} }
SS.constraint.RemoveTagged(); SK.constraint.RemoveTagged();
// And no need to do anything special, since nothing // And no need to do anything special, since nothing
// ever depends on a constraint. But do clear the // ever depends on a constraint. But do clear the
// hover, in case the just-deleted constraint was // hover, in case the just-deleted constraint was
@ -72,7 +72,7 @@ void Constraint::AddConstraint(Constraint *c) {
void Constraint::AddConstraint(Constraint *c, bool rememberForUndo) { void Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
if(rememberForUndo) SS.UndoRemember(); if(rememberForUndo) SS.UndoRemember();
SS.constraint.AddAndAssignId(c); SK.constraint.AddAndAssignId(c);
SS.MarkGroupDirty(c->group); SS.MarkGroupDirty(c->group);
SS.later.generateAll = true; SS.later.generateAll = true;
@ -119,7 +119,7 @@ void Constraint::MenuConstrain(int id) {
c.ptB = gs.point[1]; c.ptB = gs.point[1];
} else if(gs.lineSegments == 1 && gs.n == 1) { } else if(gs.lineSegments == 1 && gs.n == 1) {
c.type = PT_PT_DISTANCE; 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.ptA = e->point[0];
c.ptB = e->point[1]; c.ptB = e->point[1];
} else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) { } 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) { if(c.type == PT_PT_DISTANCE) {
Vector n = SS.GW.projRight.Cross(SS.GW.projUp); Vector n = SS.GW.projRight.Cross(SS.GW.projUp);
Vector a = SS.GetEntity(c.ptA)->PointGetNum(); Vector a = SK.GetEntity(c.ptA)->PointGetNum();
Vector b = SS.GetEntity(c.ptB)->PointGetNum(); Vector b = SK.GetEntity(c.ptB)->PointGetNum();
c.disp.offset = n.Cross(a.Minus(b)); c.disp.offset = n.Cross(a.Minus(b));
c.disp.offset = (c.disp.offset).WithMagnitude(50/SS.GW.scale); c.disp.offset = (c.disp.offset).WithMagnitude(50/SS.GW.scale);
} else { } else {
@ -240,7 +240,7 @@ void Constraint::MenuConstrain(int id) {
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
} else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) { } else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) {
c.type = EQUAL_LINE_ARC_LEN; 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.entityA = gs.entity[1];
c.entityB = gs.entity[0]; c.entityB = gs.entity[0];
} else { } else {
@ -268,10 +268,10 @@ void Constraint::MenuConstrain(int id) {
} }
if(c.type == EQUAL_ANGLE) { if(c.type == EQUAL_ANGLE) {
// Infer the nearest supplementary angle from the sketch. // Infer the nearest supplementary angle from the sketch.
Vector a1 = SS.GetEntity(c.entityA)->VectorGetNum(), Vector a1 = SK.GetEntity(c.entityA)->VectorGetNum(),
b1 = SS.GetEntity(c.entityB)->VectorGetNum(), b1 = SK.GetEntity(c.entityB)->VectorGetNum(),
a2 = SS.GetEntity(c.entityC)->VectorGetNum(), a2 = SK.GetEntity(c.entityC)->VectorGetNum(),
b2 = SS.GetEntity(c.entityD)->VectorGetNum(); b2 = SK.GetEntity(c.entityD)->VectorGetNum();
double d1 = a1.Dot(b1), d2 = a2.Dot(b2); double d1 = a1.Dot(b1), d2 = a2.Dot(b2);
if(d1*d2 < 0) { if(d1*d2 < 0) {
@ -309,7 +309,7 @@ void Constraint::MenuConstrain(int id) {
DeleteAllConstraintsFor(PT_ON_LINE, c.entityA, c.ptA); DeleteAllConstraintsFor(PT_ON_LINE, c.entityA, c.ptA);
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = AT_MIDPOINT; 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.entityA = gs.entity[i];
c.entityB = gs.entity[1-i]; c.entityB = gs.entity[1-i];
} else { } else {
@ -336,16 +336,16 @@ void Constraint::MenuConstrain(int id) {
((gs.workplanes == 1 && gs.n == 2) || ((gs.workplanes == 1 && gs.n == 2) ||
(gs.n == 1))) (gs.n == 1)))
{ {
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0; int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
Entity *line = SS.GetEntity(gs.entity[i]); Entity *line = SK.GetEntity(gs.entity[i]);
c.entityA = gs.entity[1-i]; c.entityA = gs.entity[1-i];
c.ptA = line->point[0]; c.ptA = line->point[0];
c.ptB = line->point[1]; c.ptB = line->point[1];
} else if(SS.GW.LockedInWorkplane() } else if(SS.GW.LockedInWorkplane()
&& gs.lineSegments == 2 && gs.n == 2) && gs.lineSegments == 2 && gs.n == 2)
{ {
Entity *l0 = SS.GetEntity(gs.entity[0]), Entity *l0 = SK.GetEntity(gs.entity[0]),
*l1 = SS.GetEntity(gs.entity[1]); *l1 = SK.GetEntity(gs.entity[1]);
if((l1->group.v != SS.GW.activeGroup.v) || if((l1->group.v != SS.GW.activeGroup.v) ||
(l1->construction && !(l0->construction))) (l1->construction && !(l0->construction)))
@ -384,10 +384,10 @@ void Constraint::MenuConstrain(int id) {
"symmetric without an explicit symmetry plane."); "symmetric without an explicit symmetry plane.");
return; return;
} }
Vector pa = SS.GetEntity(c.ptA)->PointGetNum(); Vector pa = SK.GetEntity(c.ptA)->PointGetNum();
Vector pb = SS.GetEntity(c.ptB)->PointGetNum(); Vector pb = SK.GetEntity(c.ptB)->PointGetNum();
Vector dp = pa.Minus(pb); 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(); Vector u = norm->NormalU(), v = norm->NormalV();
if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) { if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) {
c.type = SYMMETRIC_HORIZ; c.type = SYMMETRIC_HORIZ;
@ -419,7 +419,7 @@ void Constraint::MenuConstrain(int id) {
} }
if(gs.lineSegments == 1 && gs.n == 1) { if(gs.lineSegments == 1 && gs.n == 1) {
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
Entity *e = SS.GetEntity(c.entityA); Entity *e = SK.GetEntity(c.entityA);
ha = e->point[0]; ha = e->point[0];
hb = e->point[1]; hb = e->point[1];
} else if(gs.points == 2 && gs.n == 2) { } else if(gs.points == 2 && gs.n == 2) {
@ -454,8 +454,8 @@ void Constraint::MenuConstrain(int id) {
} }
SS.UndoRemember(); SS.UndoRemember();
Entity *nfree = SS.GetEntity(c.entityA); Entity *nfree = SK.GetEntity(c.entityA);
Entity *nref = SS.GetEntity(c.entityB); Entity *nref = SK.GetEntity(c.entityB);
if(nref->group.v == SS.GW.activeGroup.v) { if(nref->group.v == SS.GW.activeGroup.v) {
SWAP(Entity *, nref, nfree); SWAP(Entity *, nref, nfree);
} }
@ -485,7 +485,7 @@ void Constraint::MenuConstrain(int id) {
case GraphicsWindow::MNU_OTHER_ANGLE: case GraphicsWindow::MNU_OTHER_ANGLE:
if(gs.constraints == 1 && gs.n == 0) { 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) { if(c->type == ANGLE) {
SS.UndoRemember(); SS.UndoRemember();
c->other = !(c->other); c->other = !(c->other);
@ -505,10 +505,10 @@ void Constraint::MenuConstrain(int id) {
case GraphicsWindow::MNU_REFERENCE: case GraphicsWindow::MNU_REFERENCE:
if(gs.constraints == 1 && gs.n == 0) { 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) { if(c->HasLabel() && c->type != COMMENT) {
(c->reference) = !(c->reference); (c->reference) = !(c->reference);
SS.GetGroup(c->group)->clean = false; SK.GetGroup(c->group)->clean = false;
SS.GenerateAll(); SS.GenerateAll();
break; break;
} }
@ -531,15 +531,15 @@ void Constraint::MenuConstrain(int id) {
return; return;
} }
Entity *ea = SS.GetEntity(c.entityA), Entity *ea = SK.GetEntity(c.entityA),
*eb = SS.GetEntity(c.entityB); *eb = SK.GetEntity(c.entityB);
if(ea->type == Entity::LINE_SEGMENT && if(ea->type == Entity::LINE_SEGMENT &&
eb->type == Entity::LINE_SEGMENT) eb->type == Entity::LINE_SEGMENT)
{ {
Vector a0 = SS.GetEntity(ea->point[0])->PointGetNum(), Vector a0 = SK.GetEntity(ea->point[0])->PointGetNum(),
a1 = SS.GetEntity(ea->point[1])->PointGetNum(), a1 = SK.GetEntity(ea->point[1])->PointGetNum(),
b0 = SS.GetEntity(eb->point[0])->PointGetNum(), b0 = SK.GetEntity(eb->point[0])->PointGetNum(),
b1 = SS.GetEntity(eb->point[1])->PointGetNum(); b1 = SK.GetEntity(eb->point[1])->PointGetNum();
if(a0.Equals(b0) || a1.Equals(b1)) { if(a0.Equals(b0) || a1.Equals(b1)) {
// okay, vectors should be drawn in same sense // okay, vectors should be drawn in same sense
} else if(a0.Equals(b1) || a1.Equals(b0)) { } else if(a0.Equals(b1) || a1.Equals(b0)) {
@ -560,15 +560,15 @@ void Constraint::MenuConstrain(int id) {
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
} else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) {
Entity *line = SS.GetEntity(gs.entity[0]); Entity *line = SK.GetEntity(gs.entity[0]);
Entity *arc = SS.GetEntity(gs.entity[1]); Entity *arc = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::ARC_OF_CIRCLE) { if(line->type == Entity::ARC_OF_CIRCLE) {
SWAP(Entity *, line, arc); SWAP(Entity *, line, arc);
} }
Vector l0 = SS.GetEntity(line->point[0])->PointGetNum(), Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SS.GetEntity(line->point[1])->PointGetNum(); l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector a1 = SS.GetEntity(arc->point[1])->PointGetNum(), Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(),
a2 = SS.GetEntity(arc->point[2])->PointGetNum(); a2 = SK.GetEntity(arc->point[2])->PointGetNum();
if(l0.Equals(a1) || l1.Equals(a1)) { if(l0.Equals(a1) || l1.Equals(a1)) {
c.other = false; c.other = false;
@ -584,15 +584,15 @@ void Constraint::MenuConstrain(int id) {
c.entityA = arc->h; c.entityA = arc->h;
c.entityB = line->h; c.entityB = line->h;
} else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) {
Entity *line = SS.GetEntity(gs.entity[0]); Entity *line = SK.GetEntity(gs.entity[0]);
Entity *cubic = SS.GetEntity(gs.entity[1]); Entity *cubic = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::CUBIC) { if(line->type == Entity::CUBIC) {
SWAP(Entity *, line, cubic); SWAP(Entity *, line, cubic);
} }
Vector l0 = SS.GetEntity(line->point[0])->PointGetNum(), Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
l1 = SS.GetEntity(line->point[1])->PointGetNum(); l1 = SK.GetEntity(line->point[1])->PointGetNum();
Vector a0 = SS.GetEntity(cubic->point[0])->PointGetNum(), Vector a0 = SK.GetEntity(cubic->point[0])->PointGetNum(),
a3 = SS.GetEntity(cubic->point[3])->PointGetNum(); a3 = SK.GetEntity(cubic->point[3])->PointGetNum();
if(l0.Equals(a0) || l1.Equals(a0)) { if(l0.Equals(a0) || l1.Equals(a0)) {
c.other = false; 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) Expr *ConstraintBase::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln)
{ {
Entity *ln = SS.GetEntity(hln); Entity *ln = SK.GetEntity(hln);
Entity *a = SS.GetEntity(ln->point[0]); Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]); 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) { if(wrkpl.v == Entity::FREE_IN_3D.v) {
ExprVector ep = p->PointGetExprs(); ExprVector ep = p->PointGetExprs();
@ -71,13 +71,13 @@ Expr *ConstraintBase::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln)
Expr *ConstraintBase::PointPlaneDistance(ExprVector p, hEntity hpl) { Expr *ConstraintBase::PointPlaneDistance(ExprVector p, hEntity hpl) {
ExprVector n; ExprVector n;
Expr *d; Expr *d;
SS.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d); SK.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d);
return (p.Dot(n))->Minus(d); return (p.Dot(n))->Minus(d);
} }
Expr *ConstraintBase::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) { Expr *ConstraintBase::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) {
Entity *pa = SS.GetEntity(hpa); Entity *pa = SK.GetEntity(hpa);
Entity *pb = SS.GetEntity(hpb); Entity *pb = SK.GetEntity(hpb);
if(!(pa->IsPoint() && pb->IsPoint())) oops(); if(!(pa->IsPoint() && pb->IsPoint())) oops();
if(wrkpl.v == Entity::FREE_IN_3D.v) { if(wrkpl.v == Entity::FREE_IN_3D.v) {
@ -113,7 +113,7 @@ Expr *ConstraintBase::DirectionCosine(hEntity wrkpl,
Expr *mags = (ae.Magnitude())->Times(be.Magnitude()); Expr *mags = (ae.Magnitude())->Times(be.Magnitude());
return (ae.Dot(be))->Div(mags); return (ae.Dot(be))->Div(mags);
} else { } else {
Entity *w = SS.GetEntity(wrkpl); Entity *w = SK.GetEntity(wrkpl);
ExprVector u = w->Normal()->NormalExprsU(); ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV(); ExprVector v = w->Normal()->NormalExprsV();
Expr *ua = u.Dot(ae); Expr *ua = u.Dot(ae);
@ -130,7 +130,7 @@ Expr *ConstraintBase::DirectionCosine(hEntity wrkpl,
ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane, ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane,
Expr *u, Expr *v) Expr *u, Expr *v)
{ {
Entity *w = SS.GetEntity(workplane); Entity *w = SK.GetEntity(workplane);
ExprVector ub = w->Normal()->NormalExprsU(); ExprVector ub = w->Normal()->NormalExprsU();
ExprVector vb = w->Normal()->NormalExprsV(); ExprVector vb = w->Normal()->NormalExprsV();
@ -141,8 +141,8 @@ ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane,
void ConstraintBase::ModifyToSatisfy(void) { void ConstraintBase::ModifyToSatisfy(void) {
if(type == ANGLE) { if(type == ANGLE) {
Vector a = SS.GetEntity(entityA)->VectorGetNum(); Vector a = SK.GetEntity(entityA)->VectorGetNum();
Vector b = SS.GetEntity(entityB)->VectorGetNum(); Vector b = SK.GetEntity(entityB)->VectorGetNum();
if(other) a = a.ScaledBy(-1); if(other) a = a.ScaledBy(-1);
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
a = a.ProjectVectorInto(workplane); a = a.ProjectVectorInto(workplane);
@ -195,14 +195,14 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
break; break;
case PT_PLANE_DISTANCE: { case PT_PLANE_DISTANCE: {
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs(); ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0); AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0);
break; break;
} }
case PT_FACE_DISTANCE: { case PT_FACE_DISTANCE: {
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs(); ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
Entity *f = SS.GetEntity(entityA); Entity *f = SK.GetEntity(entityA);
ExprVector p0 = f->FaceGetPointExprs(); ExprVector p0 = f->FaceGetPointExprs();
ExprVector n = f->FaceGetNormalExprs(); ExprVector n = f->FaceGetNormalExprs();
AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exA), 0); 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: { case EQUAL_LENGTH_LINES: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus( AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus(
Distance(workplane, b->point[0], b->point[1])), 0); Distance(workplane, b->point[0], b->point[1])), 0);
break; break;
@ -220,7 +220,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
// These work on distance squared, since the pt-line distances are // These work on distance squared, since the pt-line distances are
// signed, and we want the absolute value. // signed, and we want the absolute value.
case EQ_LEN_PT_LINE_D: { 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 *d1 = Distance(workplane, forLen->point[0], forLen->point[1]);
Expr *d2 = PointLineDistance(workplane, ptA, entityB); Expr *d2 = PointLineDistance(workplane, ptA, entityB);
AddEq(l, (d1->Square())->Minus(d2->Square()), 0); AddEq(l, (d1->Square())->Minus(d2->Square()), 0);
@ -234,8 +234,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case LENGTH_RATIO: { case LENGTH_RATIO: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
Expr *la = Distance(workplane, a->point[0], a->point[1]); Expr *la = Distance(workplane, a->point[0], a->point[1]);
Expr *lb = Distance(workplane, b->point[0], b->point[1]); Expr *lb = Distance(workplane, b->point[0], b->point[1]);
AddEq(l, (la->Div(lb))->Minus(exA), 0); AddEq(l, (la->Div(lb))->Minus(exA), 0);
@ -243,33 +243,33 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case DIAMETER: { case DIAMETER: {
Entity *circle = SS.GetEntity(entityA); Entity *circle = SK.GetEntity(entityA);
Expr *r = circle->CircleGetRadiusExpr(); Expr *r = circle->CircleGetRadiusExpr();
AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0); AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0);
break; break;
} }
case EQUAL_RADIUS: { case EQUAL_RADIUS: {
Entity *c1 = SS.GetEntity(entityA); Entity *c1 = SK.GetEntity(entityA);
Entity *c2 = SS.GetEntity(entityB); Entity *c2 = SK.GetEntity(entityB);
AddEq(l, (c1->CircleGetRadiusExpr())->Minus( AddEq(l, (c1->CircleGetRadiusExpr())->Minus(
c2->CircleGetRadiusExpr()), 0); c2->CircleGetRadiusExpr()), 0);
break; break;
} }
case EQUAL_LINE_ARC_LEN: { case EQUAL_LINE_ARC_LEN: {
Entity *line = SS.GetEntity(entityA), Entity *line = SK.GetEntity(entityA),
*arc = SS.GetEntity(entityB); *arc = SK.GetEntity(entityB);
// Get the line length // Get the line length
ExprVector l0 = SS.GetEntity(line->point[0])->PointGetExprs(), ExprVector l0 = SK.GetEntity(line->point[0])->PointGetExprs(),
l1 = SS.GetEntity(line->point[1])->PointGetExprs(); l1 = SK.GetEntity(line->point[1])->PointGetExprs();
Expr *ll = (l1.Minus(l0)).Magnitude(); Expr *ll = (l1.Minus(l0)).Magnitude();
// And get the arc radius, and the cosine of its angle // And get the arc radius, and the cosine of its angle
Entity *ao = SS.GetEntity(arc->point[0]), Entity *ao = SK.GetEntity(arc->point[0]),
*as = SS.GetEntity(arc->point[1]), *as = SK.GetEntity(arc->point[1]),
*af = SS.GetEntity(arc->point[2]); *af = SK.GetEntity(arc->point[2]);
ExprVector aos = (as->PointGetExprs()).Minus(ao->PointGetExprs()), ExprVector aos = (as->PointGetExprs()).Minus(ao->PointGetExprs()),
aof = (af->PointGetExprs()).Minus(ao->PointGetExprs()); aof = (af->PointGetExprs()).Minus(ao->PointGetExprs());
@ -301,8 +301,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case POINTS_COINCIDENT: { case POINTS_COINCIDENT: {
Entity *a = SS.GetEntity(ptA); Entity *a = SK.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB); Entity *b = SK.GetEntity(ptB);
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
ExprVector pa = a->PointGetExprs(); ExprVector pa = a->PointGetExprs();
ExprVector pb = b->PointGetExprs(); ExprVector pb = b->PointGetExprs();
@ -323,13 +323,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_IN_PLANE: case PT_IN_PLANE:
// This one works the same, whether projected or not. // This one works the same, whether projected or not.
AddEq(l, PointPlaneDistance( AddEq(l, PointPlaneDistance(
SS.GetEntity(ptA)->PointGetExprs(), entityA), 0); SK.GetEntity(ptA)->PointGetExprs(), entityA), 0);
break; break;
case PT_ON_FACE: { case PT_ON_FACE: {
// a plane, n dot (p - p0) = 0 // a plane, n dot (p - p0) = 0
ExprVector p = SS.GetEntity(ptA)->PointGetExprs(); ExprVector p = SK.GetEntity(ptA)->PointGetExprs();
Entity *f = SS.GetEntity(entityA); Entity *f = SK.GetEntity(entityA);
ExprVector p0 = f->FaceGetPointExprs(); ExprVector p0 = f->FaceGetPointExprs();
ExprVector n = f->FaceGetNormalExprs(); ExprVector n = f->FaceGetNormalExprs();
AddEq(l, (p.Minus(p0)).Dot(n), 0); AddEq(l, (p.Minus(p0)).Dot(n), 0);
@ -338,10 +338,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_ON_LINE: case PT_ON_LINE:
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *ln = SS.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
Entity *a = SS.GetEntity(ln->point[0]); Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]); Entity *b = SK.GetEntity(ln->point[1]);
Entity *p = SS.GetEntity(ptA); Entity *p = SK.GetEntity(ptA);
ExprVector ep = p->PointGetExprs(); ExprVector ep = p->PointGetExprs();
ExprVector ea = a->PointGetExprs(); ExprVector ea = a->PointGetExprs();
@ -370,10 +370,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PT_ON_CIRCLE: { case PT_ON_CIRCLE: {
// This actually constrains the point to lie on the cylinder. // This actually constrains the point to lie on the cylinder.
Entity *circle = SS.GetEntity(entityA); Entity *circle = SK.GetEntity(entityA);
ExprVector center = SS.GetEntity(circle->point[0])->PointGetExprs(); ExprVector center = SK.GetEntity(circle->point[0])->PointGetExprs();
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs(); ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
Entity *normal = SS.GetEntity(circle->normal); Entity *normal = SK.GetEntity(circle->normal);
ExprVector u = normal->NormalExprsU(), ExprVector u = normal->NormalExprsU(),
v = normal->NormalExprsV(); v = normal->NormalExprsV();
@ -389,13 +389,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case AT_MIDPOINT: case AT_MIDPOINT:
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *ln = SS.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
ExprVector a = SS.GetEntity(ln->point[0])->PointGetExprs(); ExprVector a = SK.GetEntity(ln->point[0])->PointGetExprs();
ExprVector b = SS.GetEntity(ln->point[1])->PointGetExprs(); ExprVector b = SK.GetEntity(ln->point[1])->PointGetExprs();
ExprVector m = (a.Plus(b)).ScaledBy(Expr::From(0.5)); ExprVector m = (a.Plus(b)).ScaledBy(Expr::From(0.5));
if(ptA.v) { 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.x)->Minus(p.x), 0);
AddEq(l, (m.y)->Minus(p.y), 1); AddEq(l, (m.y)->Minus(p.y), 1);
AddEq(l, (m.z)->Minus(p.z), 2); 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); AddEq(l, PointPlaneDistance(m, entityB), 0);
} }
} else { } else {
Entity *ln = SS.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
Entity *a = SS.GetEntity(ln->point[0]); Entity *a = SK.GetEntity(ln->point[0]);
Entity *b = SS.GetEntity(ln->point[1]); Entity *b = SK.GetEntity(ln->point[1]);
Expr *au, *av, *bu, *bv; Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av); a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -414,7 +414,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
Expr *mv = Expr::From(0.5)->Times(av->Plus(bv)); Expr *mv = Expr::From(0.5)->Times(av->Plus(bv));
if(ptA.v) { if(ptA.v) {
Entity *p = SS.GetEntity(ptA); Entity *p = SK.GetEntity(ptA);
Expr *pu, *pv; Expr *pu, *pv;
p->PointGetExprsInWorkplane(workplane, &pu, &pv); p->PointGetExprsInWorkplane(workplane, &pu, &pv);
AddEq(l, pu->Minus(mu), 0); AddEq(l, pu->Minus(mu), 0);
@ -428,9 +428,9 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case SYMMETRIC: case SYMMETRIC:
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
Entity *plane = SS.GetEntity(entityA); Entity *plane = SK.GetEntity(entityA);
Entity *ea = SS.GetEntity(ptA); Entity *ea = SK.GetEntity(ptA);
Entity *eb = SS.GetEntity(ptB); Entity *eb = SK.GetEntity(ptB);
ExprVector a = ea->PointGetExprs(); ExprVector a = ea->PointGetExprs();
ExprVector b = eb->PointGetExprs(); ExprVector b = eb->PointGetExprs();
@ -447,9 +447,9 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, au->Minus(bu), 1); AddEq(l, au->Minus(bu), 1);
AddEq(l, av->Minus(bv), 2); AddEq(l, av->Minus(bv), 2);
} else { } else {
Entity *plane = SS.GetEntity(entityA); Entity *plane = SK.GetEntity(entityA);
Entity *a = SS.GetEntity(ptA); Entity *a = SK.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB); Entity *b = SK.GetEntity(ptB);
Expr *au, *av, *bu, *bv; Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av); 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 // to the symmetry pane's normal (i.e., that lies in the
// plane of symmetry). The line connecting the points is // plane of symmetry). The line connecting the points is
// perpendicular to that constructed vector. // perpendicular to that constructed vector.
Entity *w = SS.GetEntity(workplane); Entity *w = SK.GetEntity(workplane);
ExprVector u = w->Normal()->NormalExprsU(); ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV(); ExprVector v = w->Normal()->NormalExprsV();
@ -479,8 +479,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case SYMMETRIC_HORIZ: case SYMMETRIC_HORIZ:
case SYMMETRIC_VERT: { case SYMMETRIC_VERT: {
Entity *a = SS.GetEntity(ptA); Entity *a = SK.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB); Entity *b = SK.GetEntity(ptB);
Expr *au, *av, *bu, *bv; Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av); a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -497,16 +497,16 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case SYMMETRIC_LINE: { case SYMMETRIC_LINE: {
Entity *pa = SS.GetEntity(ptA); Entity *pa = SK.GetEntity(ptA);
Entity *pb = SS.GetEntity(ptB); Entity *pb = SK.GetEntity(ptB);
Expr *pau, *pav, *pbu, *pbv; Expr *pau, *pav, *pbu, *pbv;
pa->PointGetExprsInWorkplane(workplane, &pau, &pav); pa->PointGetExprsInWorkplane(workplane, &pau, &pav);
pb->PointGetExprsInWorkplane(workplane, &pbu, &pbv); pb->PointGetExprsInWorkplane(workplane, &pbu, &pbv);
Entity *ln = SS.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
Entity *la = SS.GetEntity(ln->point[0]); Entity *la = SK.GetEntity(ln->point[0]);
Entity *lb = SS.GetEntity(ln->point[1]); Entity *lb = SK.GetEntity(ln->point[1]);
Expr *lau, *lav, *lbu, *lbv; Expr *lau, *lav, *lbu, *lbv;
la->PointGetExprsInWorkplane(workplane, &lau, &lav); la->PointGetExprsInWorkplane(workplane, &lau, &lav);
lb->PointGetExprsInWorkplane(workplane, &lbu, &lbv); lb->PointGetExprsInWorkplane(workplane, &lbu, &lbv);
@ -533,15 +533,15 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case VERTICAL: { case VERTICAL: {
hEntity ha, hb; hEntity ha, hb;
if(entityA.v) { if(entityA.v) {
Entity *e = SS.GetEntity(entityA); Entity *e = SK.GetEntity(entityA);
ha = e->point[0]; ha = e->point[0];
hb = e->point[1]; hb = e->point[1];
} else { } else {
ha = ptA; ha = ptA;
hb = ptB; hb = ptB;
} }
Entity *a = SS.GetEntity(ha); Entity *a = SK.GetEntity(ha);
Entity *b = SS.GetEntity(hb); Entity *b = SK.GetEntity(hb);
Expr *au, *av, *bu, *bv; Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av); a->PointGetExprsInWorkplane(workplane, &au, &av);
@ -552,8 +552,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case SAME_ORIENTATION: { case SAME_ORIENTATION: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
if(b->group.v != group.v) { if(b->group.v != group.v) {
SWAP(Entity *, a, b); SWAP(Entity *, a, b);
} }
@ -581,8 +581,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
case PERPENDICULAR: case PERPENDICULAR:
case ANGLE: { case ANGLE: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
ExprVector ae = a->VectorGetExprs(); ExprVector ae = a->VectorGetExprs();
ExprVector be = b->VectorGetExprs(); ExprVector be = b->VectorGetExprs();
if(other) ae = ae.ScaledBy(Expr::From(-1)); if(other) ae = ae.ScaledBy(Expr::From(-1));
@ -602,10 +602,10 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case EQUAL_ANGLE: { case EQUAL_ANGLE: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
Entity *c = SS.GetEntity(entityC); Entity *c = SK.GetEntity(entityC);
Entity *d = SS.GetEntity(entityD); Entity *d = SK.GetEntity(entityD);
ExprVector ae = a->VectorGetExprs(); ExprVector ae = a->VectorGetExprs();
ExprVector be = b->VectorGetExprs(); ExprVector be = b->VectorGetExprs();
ExprVector ce = c->VectorGetExprs(); ExprVector ce = c->VectorGetExprs();
@ -621,12 +621,12 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case ARC_LINE_TANGENT: { case ARC_LINE_TANGENT: {
Entity *arc = SS.GetEntity(entityA); Entity *arc = SK.GetEntity(entityA);
Entity *line = SS.GetEntity(entityB); Entity *line = SK.GetEntity(entityB);
ExprVector ac = SS.GetEntity(arc->point[0])->PointGetExprs(); ExprVector ac = SK.GetEntity(arc->point[0])->PointGetExprs();
ExprVector ap = ExprVector ap =
SS.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs(); SK.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs();
ExprVector ld = line->VectorGetExprs(); ExprVector ld = line->VectorGetExprs();
@ -636,13 +636,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case CUBIC_LINE_TANGENT: { case CUBIC_LINE_TANGENT: {
Entity *cubic = SS.GetEntity(entityA); Entity *cubic = SK.GetEntity(entityA);
Entity *line = SS.GetEntity(entityB); Entity *line = SK.GetEntity(entityB);
ExprVector endpoint = ExprVector endpoint =
SS.GetEntity(cubic->point[other ? 3 : 0])->PointGetExprs(); SK.GetEntity(cubic->point[other ? 3 : 0])->PointGetExprs();
ExprVector ctrlpoint = ExprVector ctrlpoint =
SS.GetEntity(cubic->point[other ? 2 : 1])->PointGetExprs(); SK.GetEntity(cubic->point[other ? 2 : 1])->PointGetExprs();
ExprVector a = endpoint.Minus(ctrlpoint); 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(0, a, b), 0);
AddEq(l, VectorsParallel(1, a, b), 1); AddEq(l, VectorsParallel(1, a, b), 1);
} else { } else {
Entity *w = SS.GetEntity(workplane); Entity *w = SK.GetEntity(workplane);
ExprVector wn = w->Normal()->NormalExprsN(); ExprVector wn = w->Normal()->NormalExprsN();
AddEq(l, (a.Cross(b)).Dot(wn), 0); AddEq(l, (a.Cross(b)).Dot(wn), 0);
} }
@ -660,7 +660,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
} }
case PARALLEL: { 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) { if(eb->group.v != group.v) {
SWAP(Entity *, ea, eb); 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(0, a, b), 0);
AddEq(l, VectorsParallel(1, a, b), 1); AddEq(l, VectorsParallel(1, a, b), 1);
} else { } else {
Entity *w = SS.GetEntity(workplane); Entity *w = SK.GetEntity(workplane);
ExprVector wn = w->Normal()->NormalExprsN(); ExprVector wn = w->Normal()->NormalExprsN();
AddEq(l, (a.Cross(b)).Dot(wn), 0); AddEq(l, (a.Cross(b)).Dot(wn), 0);
} }

120
draw.cpp
View File

@ -1,7 +1,7 @@
#include "solvespace.h" #include "solvespace.h"
void GraphicsWindow::UpdateDraggedPoint(hEntity hp, double mx, double my) { void GraphicsWindow::UpdateDraggedPoint(hEntity hp, double mx, double my) {
Entity *p = SS.GetEntity(hp); Entity *p = SK.GetEntity(hp);
Vector pos = p->PointGetNum(); Vector pos = p->PointGetNum();
UpdateDraggedNum(&pos, mx, my); UpdateDraggedNum(&pos, mx, my);
p->PointForceTo(pos); p->PointForceTo(pos);
@ -80,7 +80,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// start dragging something. // start dragging something.
if(leftDown && dm > 3) { if(leftDown && dm > 3) {
if(hover.entity.v) { if(hover.entity.v) {
Entity *e = SS.GetEntity(hover.entity); Entity *e = SK.GetEntity(hover.entity);
if(e->IsPoint()) { if(e->IsPoint()) {
// Start dragging this point. // Start dragging this point.
ClearSelection(); ClearSelection();
@ -97,7 +97,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
pending.operation = DRAGGING_NORMAL; pending.operation = DRAGGING_NORMAL;
} }
} else if(hover.constraint.v && } else if(hover.constraint.v &&
SS.GetConstraint(hover.constraint)->HasLabel()) SK.GetConstraint(hover.constraint)->HasLabel())
{ {
ClearSelection(); ClearSelection();
pending.constraint = hover.constraint; pending.constraint = hover.constraint;
@ -132,7 +132,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
if(!havePainted) return; if(!havePainted) return;
switch(pending.operation) { switch(pending.operation) {
case DRAGGING_CONSTRAINT: { case DRAGGING_CONSTRAINT: {
Constraint *c = SS.constraint.FindById(pending.constraint); Constraint *c = SK.constraint.FindById(pending.constraint);
UpdateDraggedNum(&(c->disp.offset), x, y); UpdateDraggedNum(&(c->disp.offset), x, y);
break; break;
} }
@ -141,7 +141,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// and fall through // and fall through
case DRAGGING_NEW_POINT: case DRAGGING_NEW_POINT:
case DRAGGING_POINT: { case DRAGGING_POINT: {
Entity *p = SS.GetEntity(pending.point); Entity *p = SK.GetEntity(pending.point);
if((p->type == Entity::POINT_N_ROT_TRANS) && if((p->type == Entity::POINT_N_ROT_TRANS) &&
(shiftDown || ctrlDown)) (shiftDown || ctrlDown))
{ {
@ -194,12 +194,12 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
HitTestMakeSelection(mp); HitTestMakeSelection(mp);
hRequest hr = pending.point.request(); hRequest hr = pending.point.request();
Vector p0 = SS.GetEntity(hr.entity(1))->PointGetNum(); Vector p0 = SK.GetEntity(hr.entity(1))->PointGetNum();
Vector p3 = SS.GetEntity(hr.entity(4))->PointGetNum(); Vector p3 = SK.GetEntity(hr.entity(4))->PointGetNum();
Vector p1 = p0.ScaledBy(2.0/3).Plus(p3.ScaledBy(1.0/3)); 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)); 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); SS.MarkGroupDirtyByEntity(pending.point);
break; break;
@ -209,30 +209,30 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
HitTestMakeSelection(mp); HitTestMakeSelection(mp);
hRequest hr = pending.point.request(); hRequest hr = pending.point.request();
Vector ona = SS.GetEntity(hr.entity(2))->PointGetNum(); Vector ona = SK.GetEntity(hr.entity(2))->PointGetNum();
Vector onb = SS.GetEntity(hr.entity(3))->PointGetNum(); Vector onb = SK.GetEntity(hr.entity(3))->PointGetNum();
Vector center = (ona.Plus(onb)).ScaledBy(0.5); 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); SS.MarkGroupDirtyByEntity(pending.point);
break; break;
} }
case DRAGGING_NEW_RADIUS: case DRAGGING_NEW_RADIUS:
case DRAGGING_RADIUS: { case DRAGGING_RADIUS: {
Entity *circle = SS.GetEntity(pending.circle); Entity *circle = SK.GetEntity(pending.circle);
Vector center = SS.GetEntity(circle->point[0])->PointGetNum(); Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Point2d c2 = ProjectPoint(center); Point2d c2 = ProjectPoint(center);
double r = c2.DistanceTo(mp)/scale; double r = c2.DistanceTo(mp)/scale;
SS.GetEntity(circle->distance)->DistanceForceTo(r); SK.GetEntity(circle->distance)->DistanceForceTo(r);
SS.MarkGroupDirtyByEntity(pending.circle); SS.MarkGroupDirtyByEntity(pending.circle);
break; break;
} }
case DRAGGING_NORMAL: { case DRAGGING_NORMAL: {
Entity *normal = SS.GetEntity(pending.normal); Entity *normal = SK.GetEntity(pending.normal);
Vector p = SS.GetEntity(normal->point[0])->PointGetNum(); Vector p = SK.GetEntity(normal->point[0])->PointGetNum();
Point2d p2 = ProjectPoint(p); Point2d p2 = ProjectPoint(p);
Quaternion q = normal->NormalGetNum(); Quaternion q = normal->NormalGetNum();
@ -299,7 +299,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
Request r; Request r;
memset(&r, 0, sizeof(r)); memset(&r, 0, sizeof(r));
r.group = activeGroup; r.group = activeGroup;
Group *g = SS.GetGroup(activeGroup); Group *g = SK.GetGroup(activeGroup);
if(g->type == Group::DRAWING_3D || g->type == Group::DRAWING_WORKPLANE) { if(g->type == Group::DRAWING_3D || g->type == Group::DRAWING_WORKPLANE) {
r.construction = false; r.construction = false;
} else { } else {
@ -307,7 +307,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
} }
r.workplane = ActiveWorkplane(); r.workplane = ActiveWorkplane();
r.type = type; r.type = type;
SS.request.AddAndAssignId(&r); SK.request.AddAndAssignId(&r);
// We must regenerate the parameters, so that the code that tries to // 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 // 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) { bool GraphicsWindow::ConstrainPointByHovered(hEntity pt) {
if(!hover.entity.v) return false; if(!hover.entity.v) return false;
Entity *e = SS.GetEntity(hover.entity); Entity *e = SK.GetEntity(hover.entity);
if(e->IsPoint()) { if(e->IsPoint()) {
Constraint::ConstrainCoincident(e->h, pt); Constraint::ConstrainCoincident(e->h, pt);
return true; return true;
@ -362,7 +362,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
switch(pending.operation) { switch(pending.operation) {
case MNU_DATUM_POINT: case MNU_DATUM_POINT:
hr = AddRequest(Request::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)); ConstrainPointByHovered(hr.entity(0));
ClearSuper(); ClearSuper();
@ -372,7 +372,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
case MNU_LINE_SEGMENT: case MNU_LINE_SEGMENT:
hr = AddRequest(Request::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)); ConstrainPointByHovered(hr.entity(1));
ClearSuper(); ClearSuper();
@ -380,7 +380,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.operation = DRAGGING_NEW_LINE_POINT; pending.operation = DRAGGING_NEW_LINE_POINT;
pending.point = hr.entity(2); pending.point = hr.entity(2);
pending.description = "click to place next point of line"; pending.description = "click to place next point of line";
SS.GetEntity(pending.point)->PointForceTo(v); SK.GetEntity(pending.point)->PointForceTo(v);
break; break;
case MNU_RECTANGLE: { case MNU_RECTANGLE: {
@ -398,8 +398,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
Constraint::ConstrainCoincident( Constraint::ConstrainCoincident(
lns[i].entity(1), lns[(i+1)%4].entity(2)); lns[i].entity(1), lns[(i+1)%4].entity(2));
SS.GetEntity(lns[i].entity(1))->PointForceTo(v); SK.GetEntity(lns[i].entity(1))->PointForceTo(v);
SS.GetEntity(lns[i].entity(2))->PointForceTo(v); SK.GetEntity(lns[i].entity(2))->PointForceTo(v);
} }
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
Constraint::Constrain( Constraint::Constrain(
@ -416,8 +416,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
case MNU_CIRCLE: case MNU_CIRCLE:
hr = AddRequest(Request::CIRCLE); hr = AddRequest(Request::CIRCLE);
SS.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(32))->NormalForceTo( SK.GetEntity(hr.entity(32))->NormalForceTo(
Quaternion::From(SS.GW.projRight, SS.GW.projUp)); Quaternion::From(SS.GW.projRight, SS.GW.projUp));
ConstrainPointByHovered(hr.entity(1)); ConstrainPointByHovered(hr.entity(1));
@ -426,7 +426,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.operation = DRAGGING_NEW_RADIUS; pending.operation = DRAGGING_NEW_RADIUS;
pending.circle = hr.entity(0); pending.circle = hr.entity(0);
pending.description = "click to set radius"; pending.description = "click to set radius";
SS.GetParam(hr.param(0))->val = 0; SK.GetParam(hr.param(0))->val = 0;
break; break;
case MNU_ARC: { case MNU_ARC: {
@ -439,9 +439,9 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
// This fudge factor stops us from immediately failing to solve // This fudge factor stops us from immediately failing to solve
// because of the arc's implicit (equal radius) tangent. // because of the arc's implicit (equal radius) tangent.
Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale); Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale);
SS.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj)); SK.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj));
SS.GetEntity(hr.entity(2))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v);
SS.GetEntity(hr.entity(3))->PointForceTo(v); SK.GetEntity(hr.entity(3))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(2)); ConstrainPointByHovered(hr.entity(2));
ClearSuper(); ClearSuper();
@ -453,10 +453,10 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
case MNU_CUBIC: case MNU_CUBIC:
hr = AddRequest(Request::CUBIC); hr = AddRequest(Request::CUBIC);
SS.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v);
SS.GetEntity(hr.entity(3))->PointForceTo(v); SK.GetEntity(hr.entity(3))->PointForceTo(v);
SS.GetEntity(hr.entity(4))->PointForceTo(v); SK.GetEntity(hr.entity(4))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(1)); ConstrainPointByHovered(hr.entity(1));
ClearSuper(); ClearSuper();
@ -474,8 +474,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break; break;
} }
hr = AddRequest(Request::WORKPLANE); hr = AddRequest(Request::WORKPLANE);
SS.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(32))->NormalForceTo( SK.GetEntity(hr.entity(32))->NormalForceTo(
Quaternion::From(SS.GW.projRight, SS.GW.projUp)); Quaternion::From(SS.GW.projRight, SS.GW.projUp));
ConstrainPointByHovered(hr.entity(1)); ConstrainPointByHovered(hr.entity(1));
@ -489,12 +489,12 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break; break;
} }
hr = AddRequest(Request::TTF_TEXT); hr = AddRequest(Request::TTF_TEXT);
Request *r = SS.GetRequest(hr); Request *r = SK.GetRequest(hr);
r->str.strcpy("Abc"); r->str.strcpy("Abc");
r->font.strcpy("arial.ttf"); r->font.strcpy("arial.ttf");
SS.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v);
pending.operation = DRAGGING_NEW_POINT; pending.operation = DRAGGING_NEW_POINT;
pending.point = hr.entity(2); 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. // Create a new line segment, so that we continue drawing.
hRequest hr = AddRequest(Request::LINE_SEGMENT); hRequest hr = AddRequest(Request::LINE_SEGMENT);
SS.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SS.GetEntity(hr.entity(2))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v);
// Constrain the line segments to share an endpoint // Constrain the line segments to share an endpoint
Constraint::ConstrainCoincident(pending.point, hr.entity(1)); Constraint::ConstrainCoincident(pending.point, hr.entity(1));
@ -552,13 +552,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
if(i != MAX_SELECTED) break; if(i != MAX_SELECTED) break;
if(hover.entity.v != 0 && SS.GetEntity(hover.entity)->IsFace()) { if(hover.entity.v != 0 && SK.GetEntity(hover.entity)->IsFace()) {
// In the interest of speed for the triangle drawing code, // In the interest of speed for the triangle drawing code,
// only two faces may be selected at a time. // only two faces may be selected at a time.
int c = 0; int c = 0;
for(i = 0; i < MAX_SELECTED; i++) { for(i = 0; i < MAX_SELECTED; i++) {
hEntity he = selection[i].entity; hEntity he = selection[i].entity;
if(he.v != 0 && SS.GetEntity(he)->IsFace()) { if(he.v != 0 && SK.GetEntity(he)->IsFace()) {
c++; c++;
if(c >= 2) selection[i].Clear(); if(c >= 2) selection[i].Clear();
} }
@ -601,7 +601,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
constraintBeingEdited = hover.constraint; constraintBeingEdited = hover.constraint;
ClearSuper(); ClearSuper();
Constraint *c = SS.GetConstraint(constraintBeingEdited); Constraint *c = SK.GetConstraint(constraintBeingEdited);
if(c->reference) { if(c->reference) {
// Not meaningful to edit a reference dimension // Not meaningful to edit a reference dimension
return; return;
@ -631,7 +631,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
void GraphicsWindow::EditControlDone(char *s) { void GraphicsWindow::EditControlDone(char *s) {
HideGraphicsEditControl(); HideGraphicsEditControl();
Constraint *c = SS.GetConstraint(constraintBeingEdited); Constraint *c = SK.GetConstraint(constraintBeingEdited);
if(c->type == Constraint::COMMENT) { if(c->type == Constraint::COMMENT) {
SS.UndoRemember(); SS.UndoRemember();
@ -728,13 +728,13 @@ void GraphicsWindow::Selection::Draw(void) {
Vector refp; Vector refp;
if(entity.v) { if(entity.v) {
glLineWidth(1.5); glLineWidth(1.5);
Entity *e = SS.GetEntity(entity); Entity *e = SK.GetEntity(entity);
e->Draw(); e->Draw();
if(emphasized) refp = e->GetReferencePos(); if(emphasized) refp = e->GetReferencePos();
glLineWidth(1); glLineWidth(1);
} }
if(constraint.v) { if(constraint.v) {
Constraint *c = SS.GetConstraint(constraint); Constraint *c = SK.GetConstraint(constraint);
c->Draw(); c->Draw();
if(emphasized) refp = c->GetReferencePos(); if(emphasized) refp = c->GetReferencePos();
} }
@ -766,11 +766,11 @@ void GraphicsWindow::ClearNonexistentSelectionItems(void) {
bool change = false; bool change = false;
for(int i = 0; i < MAX_SELECTED; i++) { for(int i = 0; i < MAX_SELECTED; i++) {
Selection *s = &(selection[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; s->constraint.v = 0;
change = true; change = true;
} }
if(s->entity.v && !(SS.entity.FindByIdNoOops(s->entity))) { if(s->entity.v && !(SK.entity.FindByIdNoOops(s->entity))) {
s->entity.v = 0; s->entity.v = 0;
change = true; change = true;
} }
@ -786,7 +786,7 @@ void GraphicsWindow::GroupSelection(void) {
if(s->entity.v) { if(s->entity.v) {
(gs.n)++; (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. // A list of points, and a list of all entities that aren't points.
if(e->IsPoint()) { if(e->IsPoint()) {
gs.point[(gs.points)++] = s->entity; 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 // Always do the entities; we might be dragging something that should
// be auto-constrained, and we need the hover for that. // be auto-constrained, and we need the hover for that.
for(i = 0; i < SS.entity.n; i++) { for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]); Entity *e = &(SK.entity.elem[i]);
// Don't hover whatever's being dragged. // Don't hover whatever's being dragged.
if(e->h.request().v == pending.point.request().v) continue; 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. // The constraints and faces happen only when nothing's in progress.
if(pending.operation == 0) { if(pending.operation == 0) {
// Constraints // Constraints
for(i = 0; i < SS.constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
d = SS.constraint.elem[i].GetDistance(mp); d = SK.constraint.elem[i].GetDistance(mp);
if(d < 10 && d < dmin) { if(d < 10 && d < dmin) {
memset(&s, 0, sizeof(s)); memset(&s, 0, sizeof(s));
s.constraint = SS.constraint.elem[i].h; s.constraint = SK.constraint.elem[i].h;
dmin = d; dmin = d;
} }
} }
// Faces, from the triangle mesh; these are lowest priority // Faces, from the triangle mesh; these are lowest priority
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) { 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); DWORD v = m->FirstIntersectionWith(mp);
if(v) { if(v) {
s.entity.v = 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 // Draw the active group; this fills the polygons in a drawing group, and
// draws the solid mesh. // draws the solid mesh.
(SS.GetGroup(activeGroup))->Draw(); (SK.GetGroup(activeGroup))->Draw();
// Now draw the entities // Now draw the entities
if(showHdnLines) glDisable(GL_DEPTH_TEST); if(showHdnLines) glDisable(GL_DEPTH_TEST);
@ -1009,8 +1009,8 @@ void GraphicsWindow::Paint(int w, int h) {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
// Draw the constraints // Draw the constraints
for(i = 0; i < SS.constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
SS.constraint.elem[i].Draw(); SK.constraint.elem[i].Draw();
} }
// Draw the traced path, if one exists // 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) { 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(); double r = circ->CircleGetRadiusNum();
Quaternion q = circ->Normal()->NormalGetNum(); Quaternion q = circ->Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV(); 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) { void Constraint::DrawOrGetDistance(Vector *labelPos) {
if(!SS.GW.showConstraints) return; 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 // If the group is hidden, then the constraints are hidden and not
// able to be selected. // able to be selected.
if(!(g->visible)) return; if(!(g->visible)) return;
@ -210,8 +210,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
glxColor3d(1, 0.1, 1); glxColor3d(1, 0.1, 1);
switch(type) { switch(type) {
case PT_PT_DISTANCE: { case PT_PT_DISTANCE: {
Vector ap = SS.GetEntity(ptA)->PointGetNum(); Vector ap = SK.GetEntity(ptA)->PointGetNum();
Vector bp = SS.GetEntity(ptB)->PointGetNum(); Vector bp = SK.GetEntity(ptB)->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&ap); DoProjectedPoint(&ap);
@ -236,8 +236,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PT_FACE_DISTANCE: case PT_FACE_DISTANCE:
case PT_PLANE_DISTANCE: { case PT_PLANE_DISTANCE: {
Vector pt = SS.GetEntity(ptA)->PointGetNum(); Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *enta = SS.GetEntity(entityA); Entity *enta = SK.GetEntity(entityA);
Vector n, p; Vector n, p;
if(type == PT_PLANE_DISTANCE) { if(type == PT_PLANE_DISTANCE) {
n = enta->Normal()->NormalN(); n = enta->Normal()->NormalN();
@ -258,10 +258,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
case PT_LINE_DISTANCE: { case PT_LINE_DISTANCE: {
Vector pt = SS.GetEntity(ptA)->PointGetNum(); Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *line = SS.GetEntity(entityA); Entity *line = SK.GetEntity(entityA);
Vector lA = SS.GetEntity(line->point[0])->PointGetNum(); Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SS.GetEntity(line->point[1])->PointGetNum(); Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
lA = lA.ProjectInto(workplane); lA = lA.ProjectInto(workplane);
@ -282,8 +282,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
Vector lAB = (lA.Minus(lB)); Vector lAB = (lA.Minus(lB));
double t = (lA.Minus(closest)).DivPivoting(lAB); double t = (lA.Minus(closest)).DivPivoting(lAB);
Vector lA = SS.GetEntity(line->point[0])->PointGetNum(); Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SS.GetEntity(line->point[1])->PointGetNum(); Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t)); Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t));
DoProjectedPoint(&c2); DoProjectedPoint(&c2);
@ -292,8 +292,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
case DIAMETER: { case DIAMETER: {
Entity *circle = SS.GetEntity(entityA); Entity *circle = SK.GetEntity(entityA);
Vector center = SS.GetEntity(circle->point[0])->PointGetNum(); Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
double r = circle->CircleGetRadiusNum(); double r = circle->CircleGetRadiusNum();
Vector ref = center.Plus(disp.offset); Vector ref = center.Plus(disp.offset);
@ -313,7 +313,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case POINTS_COINCIDENT: { case POINTS_COINCIDENT: {
if(!dogd.drawing) { if(!dogd.drawing) {
for(int i = 0; i < 2; i++) { 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); Point2d pp = SS.GW.ProjectPoint(p);
// The point is selected within a radius of 7, from the // The point is selected within a radius of 7, from the
// same center; so if the point is visible, then this // 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 r = SS.GW.projRight.ScaledBy((a+1)/SS.GW.scale);
Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale); Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale);
for(int i = 0; i < 2; i++) { 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); glxColor3d(0.4, 0, 0.4);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glxVertex3v(p.Plus (r).Plus (d)); glxVertex3v(p.Plus (r).Plus (d));
@ -347,14 +347,14 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PT_ON_FACE: case PT_ON_FACE:
case PT_IN_PLANE: { case PT_IN_PLANE: {
double s = 8/SS.GW.scale; double s = 8/SS.GW.scale;
Vector p = SS.GetEntity(ptA)->PointGetNum(); Vector p = SK.GetEntity(ptA)->PointGetNum();
Vector r, d; Vector r, d;
if(type == PT_ON_FACE) { if(type == PT_ON_FACE) {
Vector n = SS.GetEntity(entityA)->FaceGetNormalNum(); Vector n = SK.GetEntity(entityA)->FaceGetNormalNum();
r = n.Normal(0); r = n.Normal(0);
d = n.Normal(1); d = n.Normal(1);
} else if(type == PT_IN_PLANE) { } else if(type == PT_IN_PLANE) {
Entity *n = SS.GetEntity(entityA)->Normal(); Entity *n = SK.GetEntity(entityA)->Normal();
r = n->NormalU(); r = n->NormalU();
d = n->NormalV(); d = n->NormalV();
} else { } else {
@ -372,11 +372,11 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case SAME_ORIENTATION: { case SAME_ORIENTATION: {
for(int i = 0; i < 2; i++) { 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(); Quaternion q = e->NormalGetNum();
Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale); Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale);
Vector u = q.RotationU().WithMagnitude(6/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)); p = p.Plus(n.WithMagnitude(10/SS.GW.scale));
LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n)); LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n));
@ -387,10 +387,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQUAL_ANGLE: { case EQUAL_ANGLE: {
Vector ref; Vector ref;
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
Entity *c = SS.GetEntity(entityC); Entity *c = SK.GetEntity(entityC);
Entity *d = SS.GetEntity(entityD); Entity *d = SK.GetEntity(entityD);
Vector a0 = a->VectorGetRefPoint(); Vector a0 = a->VectorGetRefPoint();
Vector b0 = b->VectorGetRefPoint(); Vector b0 = b->VectorGetRefPoint();
@ -412,8 +412,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
case ANGLE: { case ANGLE: {
Entity *a = SS.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
Vector a0 = a->VectorGetRefPoint(); Vector a0 = a->VectorGetRefPoint();
Vector b0 = b->VectorGetRefPoint(); Vector b0 = b->VectorGetRefPoint();
@ -434,13 +434,13 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
rn = gn; rn = gn;
ru = gu; ru = gu;
} else { } else {
Entity *normal = SS.GetEntity(workplane)->Normal(); Entity *normal = SK.GetEntity(workplane)->Normal();
rn = normal->NormalN(); rn = normal->NormalN();
ru = normal->NormalV(); // ru meaning r_up, not u/v ru = normal->NormalV(); // ru meaning r_up, not u/v
} }
for(int i = 0; i < 2; i++) { 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) { if(i == 0) {
// Calculate orientation of perpendicular sign only // Calculate orientation of perpendicular sign only
@ -469,11 +469,11 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
Vector textAt, u, v; Vector textAt, u, v;
if(type == ARC_LINE_TANGENT) { if(type == ARC_LINE_TANGENT) {
Entity *arc = SS.GetEntity(entityA); Entity *arc = SK.GetEntity(entityA);
Entity *norm = SS.GetEntity(arc->normal); Entity *norm = SK.GetEntity(arc->normal);
Vector c = SS.GetEntity(arc->point[0])->PointGetNum(); Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
Vector p = Vector p =
SS.GetEntity(arc->point[other ? 2 : 1])->PointGetNum(); SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
Vector r = p.Minus(c); Vector r = p.Minus(c);
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale)); textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
u = norm->NormalU(); u = norm->NormalU();
@ -485,16 +485,16 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
v = gu; v = gu;
n = gn; n = gn;
} else { } else {
Entity *wn = SS.GetEntity(workplane)->Normal(); Entity *wn = SK.GetEntity(workplane)->Normal();
u = wn->NormalU(); u = wn->NormalU();
v = wn->NormalV(); v = wn->NormalV();
n = wn->NormalN(); n = wn->NormalN();
} }
Entity *cubic = SS.GetEntity(entityA); Entity *cubic = SK.GetEntity(entityA);
Vector p = Vector p =
SS.GetEntity(cubic->point[other ? 3 : 0])->PointGetNum(); SK.GetEntity(cubic->point[other ? 3 : 0])->PointGetNum();
Vector dir = SS.GetEntity(entityB)->VectorGetNum(); Vector dir = SK.GetEntity(entityB)->VectorGetNum();
Vector out = n.Cross(dir); Vector out = n.Cross(dir);
textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale)); textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
} }
@ -515,7 +515,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case PARALLEL: { case PARALLEL: {
for(int i = 0; i < 2; i++) { 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(); Vector n = e->VectorGetNum();
n = n.WithMagnitude(25/SS.GW.scale); n = n.WithMagnitude(25/SS.GW.scale);
Vector u = (gn.Cross(n)).WithMagnitude(4/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: { case EQUAL_LINE_ARC_LEN: {
Entity *line = SS.GetEntity(entityA); Entity *line = SK.GetEntity(entityA);
DoEqualLenTicks( DoEqualLenTicks(
SS.GetEntity(line->point[0])->PointGetNum(), SK.GetEntity(line->point[0])->PointGetNum(),
SS.GetEntity(line->point[1])->PointGetNum(), SK.GetEntity(line->point[1])->PointGetNum(),
gn); gn);
DoEqualRadiusTicks(entityB); DoEqualRadiusTicks(entityB);
@ -549,9 +549,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQUAL_LENGTH_LINES: { case EQUAL_LENGTH_LINES: {
Vector a, b; Vector a, b;
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB); Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
a = SS.GetEntity(e->point[0])->PointGetNum(); a = SK.GetEntity(e->point[0])->PointGetNum();
b = SS.GetEntity(e->point[1])->PointGetNum(); b = SK.GetEntity(e->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&a); DoProjectedPoint(&a);
@ -568,19 +568,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
case EQ_LEN_PT_LINE_D: { case EQ_LEN_PT_LINE_D: {
Entity *forLen = SS.GetEntity(entityA); Entity *forLen = SK.GetEntity(entityA);
Vector a = SS.GetEntity(forLen->point[0])->PointGetNum(), Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
b = SS.GetEntity(forLen->point[1])->PointGetNum(); b = SK.GetEntity(forLen->point[1])->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&a); DoProjectedPoint(&a);
DoProjectedPoint(&b); DoProjectedPoint(&b);
} }
DoEqualLenTicks(a, b, gn); DoEqualLenTicks(a, b, gn);
Entity *ln = SS.GetEntity(entityB); Entity *ln = SK.GetEntity(entityB);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(), Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum(); lb = SK.GetEntity(ln->point[1])->PointGetNum();
Vector pt = SS.GetEntity(ptA)->PointGetNum(); Vector pt = SK.GetEntity(ptA)->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
DoProjectedPoint(&pt); DoProjectedPoint(&pt);
la = la.ProjectInto(workplane); la = la.ProjectInto(workplane);
@ -595,10 +595,10 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case EQ_PT_LN_DISTANCES: { case EQ_PT_LN_DISTANCES: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *ln = SS.GetEntity(i == 0 ? entityA : entityB); Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(), Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum(); lb = SK.GetEntity(ln->point[1])->PointGetNum();
Entity *pte = SS.GetEntity(i == 0 ? ptA : ptB); Entity *pte = SK.GetEntity(i == 0 ? ptA : ptB);
Vector pt = pte->PointGetNum(); Vector pt = pte->PointGetNum();
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
@ -618,25 +618,25 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
{ {
Vector n; Vector n;
case SYMMETRIC: case SYMMETRIC:
n = SS.GetEntity(entityA)->Normal()->NormalN(); goto s; n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s;
case SYMMETRIC_HORIZ: case SYMMETRIC_HORIZ:
n = SS.GetEntity(workplane)->Normal()->NormalU(); goto s; n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s;
case SYMMETRIC_VERT: case SYMMETRIC_VERT:
n = SS.GetEntity(workplane)->Normal()->NormalV(); goto s; n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s;
case SYMMETRIC_LINE: { case SYMMETRIC_LINE: {
Entity *ln = SS.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(), Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum(); lb = SK.GetEntity(ln->point[1])->PointGetNum();
la = la.ProjectInto(workplane); la = la.ProjectInto(workplane);
lb = lb.ProjectInto(workplane); lb = lb.ProjectInto(workplane);
n = lb.Minus(la); n = lb.Minus(la);
Vector nw = SS.GetEntity(workplane)->Normal()->NormalN(); Vector nw = SK.GetEntity(workplane)->Normal()->NormalN();
n = n.RotatedAbout(nw, PI/2); n = n.RotatedAbout(nw, PI/2);
goto s; goto s;
} }
s: s:
Vector a = SS.GetEntity(ptA)->PointGetNum(); Vector a = SK.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum(); Vector b = SK.GetEntity(ptB)->PointGetNum();
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Vector tail = (i == 0) ? a : b; Vector tail = (i == 0) ? a : b;
@ -666,14 +666,14 @@ s:
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
r = gr; u = gu; n = gn; r = gr; u = gu; n = gn;
} else { } else {
r = SS.GetEntity(workplane)->Normal()->NormalU(); r = SK.GetEntity(workplane)->Normal()->NormalU();
u = SS.GetEntity(workplane)->Normal()->NormalV(); u = SK.GetEntity(workplane)->Normal()->NormalV();
n = r.Cross(u); n = r.Cross(u);
} }
// For "at midpoint", this branch is always taken. // For "at midpoint", this branch is always taken.
Entity *e = SS.GetEntity(entityA); Entity *e = SK.GetEntity(entityA);
Vector a = SS.GetEntity(e->point[0])->PointGetNum(); Vector a = SK.GetEntity(e->point[0])->PointGetNum();
Vector b = SS.GetEntity(e->point[1])->PointGetNum(); Vector b = SK.GetEntity(e->point[1])->PointGetNum();
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5)); Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
Vector offset = (a.Minus(b)).Cross(n); Vector offset = (a.Minus(b)).Cross(n);
offset = offset.WithMagnitude(13/SS.GW.scale); offset = offset.WithMagnitude(13/SS.GW.scale);
@ -696,10 +696,10 @@ s:
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10); dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
} }
} else { } else {
Vector a = SS.GetEntity(ptA)->PointGetNum(); Vector a = SK.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum(); Vector b = SK.GetEntity(ptB)->PointGetNum();
Entity *w = SS.GetEntity(workplane); Entity *w = SK.GetEntity(workplane);
Vector cu = w->Normal()->NormalU(); Vector cu = w->Normal()->NormalU();
Vector cv = w->Normal()->NormalV(); Vector cv = w->Normal()->NormalV();
Vector cn = w->Normal()->NormalN(); Vector cn = w->Normal()->NormalN();

View File

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

View File

@ -21,8 +21,8 @@ bool EntityBase::HasVector(void) {
ExprVector EntityBase::VectorGetExprs(void) { ExprVector EntityBase::VectorGetExprs(void) {
switch(type) { switch(type) {
case LINE_SEGMENT: case LINE_SEGMENT:
return (SS.GetEntity(point[0])->PointGetExprs()).Minus( return (SK.GetEntity(point[0])->PointGetExprs()).Minus(
SS.GetEntity(point[1])->PointGetExprs()); SK.GetEntity(point[1])->PointGetExprs());
case NORMAL_IN_3D: case NORMAL_IN_3D:
case NORMAL_IN_2D: case NORMAL_IN_2D:
@ -38,8 +38,8 @@ ExprVector EntityBase::VectorGetExprs(void) {
Vector EntityBase::VectorGetNum(void) { Vector EntityBase::VectorGetNum(void) {
switch(type) { switch(type) {
case LINE_SEGMENT: case LINE_SEGMENT:
return (SS.GetEntity(point[0])->PointGetNum()).Minus( return (SK.GetEntity(point[0])->PointGetNum()).Minus(
SS.GetEntity(point[1])->PointGetNum()); SK.GetEntity(point[1])->PointGetNum());
case NORMAL_IN_3D: case NORMAL_IN_3D:
case NORMAL_IN_2D: case NORMAL_IN_2D:
@ -55,15 +55,15 @@ Vector EntityBase::VectorGetNum(void) {
Vector EntityBase::VectorGetRefPoint(void) { Vector EntityBase::VectorGetRefPoint(void) {
switch(type) { switch(type) {
case LINE_SEGMENT: case LINE_SEGMENT:
return ((SS.GetEntity(point[0])->PointGetNum()).Plus( return ((SK.GetEntity(point[0])->PointGetNum()).Plus(
SS.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5); SK.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5);
case NORMAL_IN_3D: case NORMAL_IN_3D:
case NORMAL_IN_2D: case NORMAL_IN_2D:
case NORMAL_N_COPY: case NORMAL_N_COPY:
case NORMAL_N_ROT: case NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case NORMAL_N_ROT_AA:
return SS.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
default: oops(); default: oops();
} }
@ -75,7 +75,7 @@ bool EntityBase::IsCircle(void) {
Expr *EntityBase::CircleGetRadiusExpr(void) { Expr *EntityBase::CircleGetRadiusExpr(void) {
if(type == CIRCLE) { if(type == CIRCLE) {
return SS.GetEntity(distance)->DistanceGetExpr(); return SK.GetEntity(distance)->DistanceGetExpr();
} else if(type == ARC_OF_CIRCLE) { } else if(type == ARC_OF_CIRCLE) {
return Constraint::Distance(workplane, point[0], point[1]); return Constraint::Distance(workplane, point[0], point[1]);
} else oops(); } else oops();
@ -83,10 +83,10 @@ Expr *EntityBase::CircleGetRadiusExpr(void) {
double EntityBase::CircleGetRadiusNum(void) { double EntityBase::CircleGetRadiusNum(void) {
if(type == CIRCLE) { if(type == CIRCLE) {
return SS.GetEntity(distance)->DistanceGetNum(); return SK.GetEntity(distance)->DistanceGetNum();
} else if(type == ARC_OF_CIRCLE) { } else if(type == ARC_OF_CIRCLE) {
Vector c = SS.GetEntity(point[0])->PointGetNum(); Vector c = SK.GetEntity(point[0])->PointGetNum();
Vector pa = SS.GetEntity(point[1])->PointGetNum(); Vector pa = SK.GetEntity(point[1])->PointGetNum();
return (pa.Minus(c)).Magnitude(); return (pa.Minus(c)).Magnitude();
} else oops(); } else oops();
} }
@ -97,9 +97,9 @@ void EntityBase::ArcGetAngles(double *thetaa, double *thetab, double *dtheta) {
Quaternion q = Normal()->NormalGetNum(); Quaternion q = Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV(); Vector u = q.RotationU(), v = q.RotationV();
Vector c = SS.GetEntity(point[0])->PointGetNum(); Vector c = SK.GetEntity(point[0])->PointGetNum();
Vector pa = SS.GetEntity(point[1])->PointGetNum(); Vector pa = SK.GetEntity(point[1])->PointGetNum();
Vector pb = SS.GetEntity(point[2])->PointGetNum(); Vector pb = SK.GetEntity(point[2])->PointGetNum();
Point2d c2 = c.Project2d(u, v); Point2d c2 = c.Project2d(u, v);
Point2d pa2 = (pa.Project2d(u, v)).Minus(c2); Point2d pa2 = (pa.Project2d(u, v)).Minus(c2);
@ -119,18 +119,18 @@ bool EntityBase::IsWorkplane(void) {
} }
ExprVector EntityBase::WorkplaneGetOffsetExprs(void) { ExprVector EntityBase::WorkplaneGetOffsetExprs(void) {
return SS.GetEntity(point[0])->PointGetExprs(); return SK.GetEntity(point[0])->PointGetExprs();
} }
Vector EntityBase::WorkplaneGetOffset(void) { Vector EntityBase::WorkplaneGetOffset(void) {
return SS.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
} }
void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) { void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) {
if(type == WORKPLANE) { if(type == WORKPLANE) {
*n = Normal()->NormalExprsN(); *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 // The plane is n dot (p - p0) = 0, or
// n dot p - n dot p0 = 0 // n dot p - n dot p0 = 0
// so dn = n dot p0 // so dn = n dot p0
@ -142,7 +142,7 @@ void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) {
double EntityBase::DistanceGetNum(void) { double EntityBase::DistanceGetNum(void) {
if(type == DISTANCE) { if(type == DISTANCE) {
return SS.GetParam(param[0])->val; return SK.GetParam(param[0])->val;
} else if(type == DISTANCE_N_COPY) { } else if(type == DISTANCE_N_COPY) {
return numDistance; return numDistance;
} else oops(); } else oops();
@ -156,14 +156,14 @@ Expr *EntityBase::DistanceGetExpr(void) {
} }
void EntityBase::DistanceForceTo(double v) { void EntityBase::DistanceForceTo(double v) {
if(type == DISTANCE) { if(type == DISTANCE) {
(SS.GetParam(param[0]))->val = v; (SK.GetParam(param[0]))->val = v;
} else if(type == DISTANCE_N_COPY) { } else if(type == DISTANCE_N_COPY) {
// do nothing, it's locked // do nothing, it's locked
} else oops(); } else oops();
} }
Entity *EntityBase::Normal(void) { Entity *EntityBase::Normal(void) {
return SS.GetEntity(normal); return SK.GetEntity(normal);
} }
bool EntityBase::IsPoint(void) { bool EntityBase::IsPoint(void) {
@ -202,8 +202,8 @@ Quaternion EntityBase::NormalGetNum(void) {
break; break;
case NORMAL_IN_2D: { case NORMAL_IN_2D: {
Entity *wrkpl = SS.GetEntity(workplane); Entity *wrkpl = SK.GetEntity(workplane);
Entity *norm = SS.GetEntity(wrkpl->normal); Entity *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetNum(); q = norm->NormalGetNum();
break; break;
} }
@ -230,10 +230,10 @@ Quaternion EntityBase::NormalGetNum(void) {
void EntityBase::NormalForceTo(Quaternion q) { void EntityBase::NormalForceTo(Quaternion q) {
switch(type) { switch(type) {
case NORMAL_IN_3D: case NORMAL_IN_3D:
SS.GetParam(param[0])->val = q.w; SK.GetParam(param[0])->val = q.w;
SS.GetParam(param[1])->val = q.vx; SK.GetParam(param[1])->val = q.vx;
SS.GetParam(param[2])->val = q.vy; SK.GetParam(param[2])->val = q.vy;
SS.GetParam(param[3])->val = q.vz; SK.GetParam(param[3])->val = q.vz;
break; break;
case NORMAL_IN_2D: case NORMAL_IN_2D:
@ -243,10 +243,10 @@ void EntityBase::NormalForceTo(Quaternion q) {
case NORMAL_N_ROT: { case NORMAL_N_ROT: {
Quaternion qp = q.Times(numNormal.Inverse()); Quaternion qp = q.Times(numNormal.Inverse());
SS.GetParam(param[0])->val = qp.w; SK.GetParam(param[0])->val = qp.w;
SS.GetParam(param[1])->val = qp.vx; SK.GetParam(param[1])->val = qp.vx;
SS.GetParam(param[2])->val = qp.vy; SK.GetParam(param[2])->val = qp.vy;
SS.GetParam(param[3])->val = qp.vz; SK.GetParam(param[3])->val = qp.vz;
break; break;
} }
@ -286,8 +286,8 @@ ExprQuaternion EntityBase::NormalGetExprs(void) {
break; break;
case NORMAL_IN_2D: { case NORMAL_IN_2D: {
Entity *wrkpl = SS.GetEntity(workplane); Entity *wrkpl = SK.GetEntity(workplane);
Entity *norm = SS.GetEntity(wrkpl->normal); Entity *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetExprs(); q = norm->NormalGetExprs();
break; break;
} }
@ -322,25 +322,25 @@ bool EntityBase::PointIsFromReferences(void) {
void EntityBase::PointForceTo(Vector p) { void EntityBase::PointForceTo(Vector p) {
switch(type) { switch(type) {
case POINT_IN_3D: case POINT_IN_3D:
SS.GetParam(param[0])->val = p.x; SK.GetParam(param[0])->val = p.x;
SS.GetParam(param[1])->val = p.y; SK.GetParam(param[1])->val = p.y;
SS.GetParam(param[2])->val = p.z; SK.GetParam(param[2])->val = p.z;
break; break;
case POINT_IN_2D: { case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane); Entity *c = SK.GetEntity(workplane);
p = p.Minus(c->WorkplaneGetOffset()); p = p.Minus(c->WorkplaneGetOffset());
SS.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU()); SK.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU());
SS.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV()); SK.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV());
break; break;
} }
case POINT_N_TRANS: { case POINT_N_TRANS: {
if(timesApplied == 0) break; if(timesApplied == 0) break;
Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied); Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
SS.GetParam(param[0])->val = trans.x; SK.GetParam(param[0])->val = trans.x;
SS.GetParam(param[1])->val = trans.y; SK.GetParam(param[1])->val = trans.y;
SS.GetParam(param[2])->val = trans.z; SK.GetParam(param[2])->val = trans.z;
break; break;
} }
@ -349,9 +349,9 @@ void EntityBase::PointForceTo(Vector p) {
// remember that we're working with respect to the rotated // remember that we're working with respect to the rotated
// point. // point.
Vector trans = p.Minus(PointGetQuaternion().Rotate(numPoint)); Vector trans = p.Minus(PointGetQuaternion().Rotate(numPoint));
SS.GetParam(param[0])->val = trans.x; SK.GetParam(param[0])->val = trans.x;
SS.GetParam(param[1])->val = trans.y; SK.GetParam(param[1])->val = trans.y;
SS.GetParam(param[2])->val = trans.z; SK.GetParam(param[2])->val = trans.z;
break; break;
} }
@ -364,13 +364,13 @@ void EntityBase::PointForceTo(Vector p) {
double thetap = atan2(v.Dot(po), u.Dot(po)); double thetap = atan2(v.Dot(po), u.Dot(po));
double thetan = atan2(v.Dot(numo), u.Dot(numo)); double thetan = atan2(v.Dot(numo), u.Dot(numo));
double thetaf = (thetap - thetan); 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; double dtheta = thetaf - thetai;
// Take the smallest possible change in the actual step angle, // Take the smallest possible change in the actual step angle,
// in order to avoid jumps when you cross from +pi to -pi // in order to avoid jumps when you cross from +pi to -pi
while(dtheta < -PI) dtheta += 2*PI; while(dtheta < -PI) dtheta += 2*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; break;
} }
@ -390,11 +390,11 @@ Vector EntityBase::PointGetNum(void) {
break; break;
case POINT_IN_2D: { case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane); Entity *c = SK.GetEntity(workplane);
Vector u = c->Normal()->NormalU(); Vector u = c->Normal()->NormalU();
Vector v = c->Normal()->NormalV(); Vector v = c->Normal()->NormalV();
p = u.ScaledBy(SS.GetParam(param[0])->val); p = u.ScaledBy(SK.GetParam(param[0])->val);
p = p.Plus(v.ScaledBy(SS.GetParam(param[1])->val)); p = p.Plus(v.ScaledBy(SK.GetParam(param[1])->val));
p = p.Plus(c->WorkplaneGetOffset()); p = p.Plus(c->WorkplaneGetOffset());
break; break;
} }
@ -439,7 +439,7 @@ ExprVector EntityBase::PointGetExprs(void) {
break; break;
case POINT_IN_2D: { case POINT_IN_2D: {
Entity *c = SS.GetEntity(workplane); Entity *c = SK.GetEntity(workplane);
ExprVector u = c->Normal()->NormalExprsU(); ExprVector u = c->Normal()->NormalExprsU();
ExprVector v = c->Normal()->NormalExprsV(); ExprVector v = c->Normal()->NormalExprsV();
r = c->WorkplaneGetOffsetExprs(); r = c->WorkplaneGetOffsetExprs();
@ -488,7 +488,7 @@ void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) {
*v = Expr::From(param[1]); *v = Expr::From(param[1]);
} else { } else {
// Get the offset and basis vectors for this weird exotic csys. // 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 wp = w->WorkplaneGetOffsetExprs();
ExprVector wu = w->Normal()->NormalExprsU(); ExprVector wu = w->Normal()->NormalExprsU();
ExprVector wv = w->Normal()->NormalExprsV(); ExprVector wv = w->Normal()->NormalExprsV();
@ -505,20 +505,20 @@ void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) {
void EntityBase::PointForceQuaternionTo(Quaternion q) { void EntityBase::PointForceQuaternionTo(Quaternion q) {
if(type != POINT_N_ROT_TRANS) oops(); if(type != POINT_N_ROT_TRANS) oops();
SS.GetParam(param[3])->val = q.w; SK.GetParam(param[3])->val = q.w;
SS.GetParam(param[4])->val = q.vx; SK.GetParam(param[4])->val = q.vx;
SS.GetParam(param[5])->val = q.vy; SK.GetParam(param[5])->val = q.vy;
SS.GetParam(param[6])->val = q.vz; SK.GetParam(param[6])->val = q.vz;
} }
Quaternion EntityBase::GetAxisAngleQuaternion(int param0) { Quaternion EntityBase::GetAxisAngleQuaternion(int param0) {
Quaternion q; 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); double s = sin(theta), c = cos(theta);
q.w = c; q.w = c;
q.vx = s*SS.GetParam(param[param0+1])->val; q.vx = s*SK.GetParam(param[param0+1])->val;
q.vy = s*SS.GetParam(param[param0+2])->val; q.vy = s*SK.GetParam(param[param0+2])->val;
q.vz = s*SS.GetParam(param[param0+3])->val; q.vz = s*SK.GetParam(param[param0+3])->val;
return q; return q;
} }
@ -615,7 +615,7 @@ Vector EntityBase::FaceGetNormalNum(void) {
ExprVector EntityBase::FaceGetPointExprs(void) { ExprVector EntityBase::FaceGetPointExprs(void) {
ExprVector r; ExprVector r;
if(type == FACE_NORMAL_PT) { if(type == FACE_NORMAL_PT) {
r = SS.GetEntity(point[0])->PointGetExprs(); r = SK.GetEntity(point[0])->PointGetExprs();
} else if(type == FACE_XPROD) { } else if(type == FACE_XPROD) {
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
} else if(type == FACE_N_ROT_TRANS) { } else if(type == FACE_N_ROT_TRANS) {
@ -644,7 +644,7 @@ ExprVector EntityBase::FaceGetPointExprs(void) {
Vector EntityBase::FaceGetPointNum(void) { Vector EntityBase::FaceGetPointNum(void) {
Vector r; Vector r;
if(type == FACE_NORMAL_PT) { if(type == FACE_NORMAL_PT) {
r = SS.GetEntity(point[0])->PointGetNum(); r = SK.GetEntity(point[0])->PointGetNum();
} else if(type == FACE_XPROD) { } else if(type == FACE_XPROD) {
r = numPoint; r = numPoint;
} else if(type == FACE_N_ROT_TRANS) { } 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 // If this is a copied entity, with its point already fixed
// with respect to each other, then we don't want to generate // with respect to each other, then we don't want to generate
// the distance constraint! // 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 *ra = Constraint::Distance(workplane, point[0], point[1]);
Expr *rb = Constraint::Distance(workplane, point[0], point[2]); Expr *rb = Constraint::Distance(workplane, point[0], point[2]);
AddEq(l, ra->Minus(rb), 0); 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); Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
gn = gn.WithMagnitude(1); gn = gn.WithMagnitude(1);
Group *g = SS.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
if(g->runningMesh.l.n == 0) { if(g->runningMesh.l.n == 0) {
Error("No solid model present; draw one with extrudes and revolves, " Error("No solid model present; draw one with extrudes and revolves, "
"or use Export 2d View to export bare lines and curves."); "or use Export 2d View to export bare lines and curves.");
@ -20,21 +20,21 @@ void SolveSpace::ExportSectionTo(char *filename) {
SS.GW.GroupSelection(); SS.GW.GroupSelection();
#define gs (SS.GW.gs) #define gs (SS.GW.gs)
if((gs.n == 0 && g->activeWorkplane.v != Entity::FREE_IN_3D.v)) { 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(); origin = wrkpl->WorkplaneGetOffset();
n = wrkpl->Normal()->NormalN(); n = wrkpl->Normal()->NormalN();
u = wrkpl->Normal()->NormalU(); u = wrkpl->Normal()->NormalU();
v = wrkpl->Normal()->NormalV(); v = wrkpl->Normal()->NormalV();
} else if(gs.n == 1 && gs.faces == 1) { } 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(); origin = face->FaceGetPointNum();
n = face->FaceGetNormalNum(); n = face->FaceGetNormalNum();
if(n.Dot(gn) < 0) n = n.ScaledBy(-1); if(n.Dot(gn) < 0) n = n.ScaledBy(-1);
u = n.Normal(0); u = n.Normal(0);
v = n.Normal(1); v = n.Normal(1);
} else if(gs.n == 3 && gs.vectors == 2 && gs.points == 1) { } else if(gs.n == 3 && gs.vectors == 2 && gs.points == 1) {
Vector ut = SS.GetEntity(gs.entity[0])->VectorGetNum(), Vector ut = SK.GetEntity(gs.entity[0])->VectorGetNum(),
vt = SS.GetEntity(gs.entity[1])->VectorGetNum(); vt = SK.GetEntity(gs.entity[1])->VectorGetNum();
ut = ut.WithMagnitude(1); ut = ut.WithMagnitude(1);
vt = vt.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.projRight.Dot(ut) < 0) ut = ut.ScaledBy(-1);
if(SS.GW.projUp. Dot(vt) < 0) vt = vt.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); n = ut.Cross(vt);
u = ut.WithMagnitude(1); u = ut.WithMagnitude(1);
v = (n.Cross(u)).WithMagnitude(1); v = (n.Cross(u)).WithMagnitude(1);
@ -95,14 +95,14 @@ void SolveSpace::ExportViewTo(char *filename) {
SMesh *sm = NULL; SMesh *sm = NULL;
if(SS.GW.showShaded) { if(SS.GW.showShaded) {
sm = &((SS.GetGroup(SS.GW.activeGroup))->runningMesh); sm = &((SK.GetGroup(SS.GW.activeGroup))->runningMesh);
} }
if(sm->l.n == 0) { if(sm->l.n == 0) {
sm = NULL; sm = NULL;
} }
for(i = 0; i < SS.entity.n; i++) { for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]); Entity *e = &(SK.entity.elem[i]);
if(!e->IsVisible()) continue; if(!e->IsVisible()) continue;
if(e->construction) continue; if(e->construction) continue;
@ -119,7 +119,7 @@ void SolveSpace::ExportViewTo(char *filename) {
} }
if(SS.GW.showEdges) { if(SS.GW.showEdges) {
SEdgeList *selr = &((SS.GetGroup(SS.GW.activeGroup))->runningEdges); SEdgeList *selr = &((SK.GetGroup(SS.GW.activeGroup))->runningEdges);
SEdge *se; SEdge *se;
for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) { for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
edges.AddEdge(se->a, se->b); edges.AddEdge(se->a, se->b);
@ -973,7 +973,7 @@ void HpglFileWriter::FinishAndCloseFile(void) {
// not self-intersecting, so not much to do. // not self-intersecting, so not much to do.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SolveSpace::ExportMeshTo(char *filename) { 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) { if(m->l.n == 0) {
Error("Active group mesh is empty; nothing to export."); Error("Active group mesh is empty; nothing to export.");
return; return;

View File

@ -299,7 +299,7 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
double Expr::Eval(void) { double Expr::Eval(void) {
switch(op) { 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 PARAM_PTR: return (x.parp)->val;
case CONSTANT: return x.v; case CONSTANT: return x.v;

View File

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

View File

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

View File

@ -302,6 +302,13 @@ void glxDrawEdges(SEdgeList *el)
glxVertex3v(se->b); glxVertex3v(se->b);
} }
glEnd(); 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) void glxDebugMesh(SMesh *m)

View File

@ -136,8 +136,8 @@ void GraphicsWindow::Init(void) {
orig.projUp = projUp; orig.projUp = projUp;
// And with the last group active // And with the last group active
activeGroup = SS.group.elem[SS.group.n-1].h; activeGroup = SK.group.elem[SK.group.n-1].h;
SS.GetGroup(activeGroup)->Activate(); SK.GetGroup(activeGroup)->Activate();
showWorkplanes = false; showWorkplanes = false;
showNormals = true; showNormals = true;
@ -201,9 +201,9 @@ Vector GraphicsWindow::ProjectPoint4(Vector p, double *w) {
void GraphicsWindow::AnimateOntoWorkplane(void) { void GraphicsWindow::AnimateOntoWorkplane(void) {
if(!LockedInWorkplane()) return; if(!LockedInWorkplane()) return;
Entity *w = SS.GetEntity(ActiveWorkplane()); Entity *w = SK.GetEntity(ActiveWorkplane());
Quaternion quatf = w->Normal()->NormalGetNum(); 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); AnimateOnto(quatf, offsetf);
} }
@ -268,8 +268,8 @@ void GraphicsWindow::LoopOverPoints(
HandlePointForZoomToFit(Vector::From(0, 0, 0), pmax, pmin, wmin, div); HandlePointForZoomToFit(Vector::From(0, 0, 0), pmax, pmin, wmin, div);
int i, j; int i, j;
for(i = 0; i < SS.entity.n; i++) { for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]); Entity *e = &(SK.entity.elem[i]);
if(!e->IsVisible()) continue; if(!e->IsVisible()) continue;
if(e->IsPoint()) { if(e->IsPoint()) {
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, div); 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 // reasonable without the mesh, because a zoom to fit is used to
// set the zoom level to set the chord tol. // set the zoom level to set the chord tol.
double r = e->CircleGetRadiusNum(); double r = e->CircleGetRadiusNum();
Vector c = SS.GetEntity(e->point[0])->PointGetNum(); Vector c = SK.GetEntity(e->point[0])->PointGetNum();
Quaternion q = SS.GetEntity(e->normal)->NormalGetNum(); Quaternion q = SK.GetEntity(e->normal)->NormalGetNum();
for(j = 0; j < 4; j++) { for(j = 0; j < 4; j++) {
Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) : Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) :
(j == 1) ? (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++) { for(i = 0; i < g->runningMesh.l.n; i++) {
STriangle *tr = &(g->runningMesh.l.elem[i]); STriangle *tr = &(g->runningMesh.l.elem[i]);
HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, div); 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) { if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
Quaternion quat0; Quaternion quat0;
// Offset is the selected point, quaternion is same as before // 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); quat0 = Quaternion::From(SS.GW.projRight, SS.GW.projUp);
SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1)); SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1));
SS.GW.ClearSelection(); SS.GW.ClearSelection();
@ -461,15 +461,15 @@ void GraphicsWindow::MenuView(int id) {
void GraphicsWindow::EnsureValidActives(void) { void GraphicsWindow::EnsureValidActives(void) {
bool change = false; bool change = false;
// The active group must exist, and not be the references. // 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)) { if((!g) || (g->h.v == Group::HGROUP_REFERENCES.v)) {
int i; int i;
for(i = 0; i < SS.group.n; i++) { for(i = 0; i < SK.group.n; i++) {
if(SS.group.elem[i].h.v != Group::HGROUP_REFERENCES.v) { if(SK.group.elem[i].h.v != Group::HGROUP_REFERENCES.v) {
break; break;
} }
} }
if(i >= SS.group.n) { if(i >= SK.group.n) {
// This can happen if the user deletes all the groups in the // This can happen if the user deletes all the groups in the
// sketch. It's difficult to prevent that, because the last // sketch. It's difficult to prevent that, because the last
// group might have been deleted automatically, because it failed // group might have been deleted automatically, because it failed
@ -478,15 +478,15 @@ void GraphicsWindow::EnsureValidActives(void) {
// to delete the references, though. // to delete the references, though.
activeGroup = SS.CreateDefaultDrawingGroup(); activeGroup = SS.CreateDefaultDrawingGroup();
} else { } else {
activeGroup = SS.group.elem[i].h; activeGroup = SK.group.elem[i].h;
} }
SS.GetGroup(activeGroup)->Activate(); SK.GetGroup(activeGroup)->Activate();
change = true; change = true;
} }
// The active coordinate system must also exist. // The active coordinate system must also exist.
if(LockedInWorkplane()) { if(LockedInWorkplane()) {
Entity *e = SS.entity.FindByIdNoOops(ActiveWorkplane()); Entity *e = SK.entity.FindByIdNoOops(ActiveWorkplane());
if(e) { if(e) {
hGroup hgw = e->group; hGroup hgw = e->group;
if(hgw.v != activeGroup.v && SS.GroupsInOrder(activeGroup, hgw)) { if(hgw.v != activeGroup.v && SS.GroupsInOrder(activeGroup, hgw)) {
@ -527,10 +527,10 @@ void GraphicsWindow::EnsureValidActives(void) {
} }
void GraphicsWindow::SetWorkplaneFreeIn3d(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) { hEntity GraphicsWindow::ActiveWorkplane(void) {
Group *g = SS.group.FindByIdNoOops(activeGroup); Group *g = SK.group.FindByIdNoOops(activeGroup);
if(g) { if(g) {
return g->activeWorkplane; return g->activeWorkplane;
} else { } else {
@ -550,7 +550,7 @@ void GraphicsWindow::ForceTextWindowShown(void) {
} }
void GraphicsWindow::DeleteTaggedRequests(void) { void GraphicsWindow::DeleteTaggedRequests(void) {
SS.request.RemoveTagged(); SK.request.RemoveTagged();
// An edit might be in progress for the just-deleted item. So // An edit might be in progress for the just-deleted item. So
// now it's not. // now it's not.
@ -583,8 +583,8 @@ void GraphicsWindow::MenuEdit(int id) {
SS.UndoRemember(); SS.UndoRemember();
int i; int i;
SS.request.ClearTags(); SK.request.ClearTags();
SS.constraint.ClearTags(); SK.constraint.ClearTags();
for(i = 0; i < MAX_SELECTED; i++) { for(i = 0; i < MAX_SELECTED; i++) {
Selection *s = &(SS.GW.selection[i]); Selection *s = &(SS.GW.selection[i]);
hRequest r; r.v = 0; hRequest r; r.v = 0;
@ -592,14 +592,14 @@ void GraphicsWindow::MenuEdit(int id) {
r = s->entity.request(); r = s->entity.request();
} }
if(r.v && !r.IsFromReferences()) { if(r.v && !r.IsFromReferences()) {
SS.request.Tag(r, 1); SK.request.Tag(r, 1);
} }
if(s->constraint.v) { 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(); SS.GW.DeleteTaggedRequests();
break; break;
} }
@ -627,7 +627,7 @@ void GraphicsWindow::MenuRequest(int id) {
switch(id) { switch(id) {
case MNU_SEL_WORKPLANE: { case MNU_SEL_WORKPLANE: {
SS.GW.GroupSelection(); 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) { if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) {
// A user-selected workplane // A user-selected workplane
@ -683,7 +683,7 @@ c:
for(i = 0; i < SS.GW.gs.entities; i++) { for(i = 0; i < SS.GW.gs.entities; i++) {
hEntity he = SS.GW.gs.entity[i]; hEntity he = SS.GW.gs.entity[i];
if(!he.isFromRequest()) continue; if(!he.isFromRequest()) continue;
Request *r = SS.GetRequest(he.request()); Request *r = SK.GetRequest(he.request());
r->construction = !(r->construction); r->construction = !(r->construction);
SS.MarkGroupDirty(r->group); 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) { 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 " Error("The free version of this software does not support more "
"than six groups.\r\n\r\n" "than six groups.\r\n\r\n"
"To remove this restriction, please choose Help -> " "To remove this restriction, please choose Help -> "
@ -63,8 +63,8 @@ void Group::MenuGroup(int id) {
g.predef.entityB = gs.entity[0]; g.predef.entityB = gs.entity[0];
g.predef.entityC = gs.entity[1]; g.predef.entityC = gs.entity[1];
Vector ut = SS.GetEntity(g.predef.entityB)->VectorGetNum(); Vector ut = SK.GetEntity(g.predef.entityB)->VectorGetNum();
Vector vt = SS.GetEntity(g.predef.entityC)->VectorGetNum(); Vector vt = SK.GetEntity(g.predef.entityC)->VectorGetNum();
ut = ut.WithMagnitude(1); ut = ut.WithMagnitude(1);
vt = vt.WithMagnitude(1); vt = vt.WithMagnitude(1);
@ -98,7 +98,7 @@ void Group::MenuGroup(int id) {
g.predef.origin = gs.point[0]; g.predef.origin = gs.point[0];
g.predef.entityB = gs.vector[0]; g.predef.entityB = gs.vector[0];
} else if(gs.lineSegments == 1 && gs.n == 1) { } 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]; g.predef.entityB = gs.entity[0];
// since a line segment is a vector // since a line segment is a vector
} else { } else {
@ -120,14 +120,14 @@ void Group::MenuGroup(int id) {
// Get the group one before the active group; that's our // Get the group one before the active group; that's our
// trajectory // trajectory
int i; int i;
for(i = 1; i < SS.group.n - 1; i++) { for(i = 1; i < SK.group.n - 1; i++) {
Group *gnext = &(SS.group.elem[i+1]); Group *gnext = &(SK.group.elem[i+1]);
if(gnext->h.v == SS.GW.activeGroup.v) { if(gnext->h.v == SS.GW.activeGroup.v) {
g.opA = SS.group.elem[i].h; g.opA = SK.group.elem[i].h;
break; break;
} }
} }
if(i >= SS.group.n - 1) { if(i >= SK.group.n - 1) {
Error("At least one sketch before the active sketch must " Error("At least one sketch before the active sketch must "
"exist; that specifies the sweep trajectory."); "exist; that specifies the sweep trajectory.");
return; return;
@ -140,10 +140,10 @@ void Group::MenuGroup(int id) {
case GraphicsWindow::MNU_GROUP_HELICAL: { case GraphicsWindow::MNU_GROUP_HELICAL: {
if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) { if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) {
Vector pt = SS.GetEntity(gs.point[0])->PointGetNum(); Vector pt = SK.GetEntity(gs.point[0])->PointGetNum();
Entity *ln = SS.GetEntity(gs.entity[0]); Entity *ln = SK.GetEntity(gs.entity[0]);
Vector lpa = SS.GetEntity(ln->point[0])->PointGetNum(); Vector lpa = SK.GetEntity(ln->point[0])->PointGetNum();
Vector lpb = SS.GetEntity(ln->point[1])->PointGetNum(); Vector lpb = SK.GetEntity(ln->point[1])->PointGetNum();
double d = pt.DistanceToLine(lpa, lpb.Minus(lpa)); double d = pt.DistanceToLine(lpa, lpb.Minus(lpa));
if(d < LENGTH_EPS) { if(d < LENGTH_EPS) {
Error("Point on helix can't lie on helix's axis!"); 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: { case GraphicsWindow::MNU_GROUP_ROT: {
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) { if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
g.predef.origin = gs.point[0]; 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.predef.entityB = w->Normal()->h;
g.activeWorkplane = w->h; g.activeWorkplane = w->h;
} else if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { } else if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) {
@ -220,8 +220,8 @@ void Group::MenuGroup(int id) {
SS.GW.ClearSelection(); SS.GW.ClearSelection();
SS.UndoRemember(); SS.UndoRemember();
SS.group.AddAndAssignId(&g); SK.group.AddAndAssignId(&g);
Group *gg = SS.GetGroup(g.h); Group *gg = SK.GetGroup(g.h);
if(gg->type == IMPORTED) { if(gg->type == IMPORTED) {
SS.ReloadAllImported(); SS.ReloadAllImported();
@ -277,8 +277,8 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
case DRAWING_WORKPLANE: { case DRAWING_WORKPLANE: {
Quaternion q; Quaternion q;
if(subtype == WORKPLANE_BY_LINE_SEGMENTS) { if(subtype == WORKPLANE_BY_LINE_SEGMENTS) {
Vector u = SS.GetEntity(predef.entityB)->VectorGetNum(); Vector u = SK.GetEntity(predef.entityB)->VectorGetNum();
Vector v = SS.GetEntity(predef.entityC)->VectorGetNum(); Vector v = SK.GetEntity(predef.entityC)->VectorGetNum();
u = u.WithMagnitude(1); u = u.WithMagnitude(1);
Vector n = u.Cross(v); Vector n = u.Cross(v);
v = (n.Cross(u)).WithMagnitude(1); v = (n.Cross(u)).WithMagnitude(1);
@ -304,7 +304,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
Entity point; Entity point;
memset(&point, 0, sizeof(point)); memset(&point, 0, sizeof(point));
point.type = Entity::POINT_N_COPY; point.type = Entity::POINT_N_COPY;
point.numPoint = SS.GetEntity(predef.origin)->PointGetNum(); point.numPoint = SK.GetEntity(predef.origin)->PointGetNum();
point.group = h; point.group = h;
point.h = h.entity(2); point.h = h.entity(2);
entity->Add(&point); entity->Add(&point);
@ -344,11 +344,11 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
hEntity he = e->h; e = NULL; hEntity he = e->h; e = NULL;
// As soon as I call CopyEntity, e may become invalid! That // As soon as I call CopyEntity, e may become invalid! That
// adds entities, which may cause a realloc. // 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), h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true, false); 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), h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
true, false); true, false);
@ -477,12 +477,12 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
// The axis and center of rotation are specified numerically // The axis and center of rotation are specified numerically
#define EC(x) (Expr::From(x)) #define EC(x) (Expr::From(x))
#define EP(x) (Expr::From(h.param(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.x)->Minus(EP(0)), 0);
AddEq(l, (orig.y)->Minus(EP(1)), 1); AddEq(l, (orig.y)->Minus(EP(1)), 1);
AddEq(l, (orig.z)->Minus(EP(2)), 2); AddEq(l, (orig.z)->Minus(EP(2)), 2);
// param 3 is the angle, which is free // 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); axis = axis.WithMagnitude(1);
AddEq(l, (EC(axis.x))->Minus(EP(4)), 3); AddEq(l, (EC(axis.x))->Minus(EP(4)), 3);
AddEq(l, (EC(axis.y))->Minus(EP(5)), 4); 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) { if(predef.entityB.v != Entity::FREE_IN_3D.v) {
// The extrusion path is locked along a line, normal to the // The extrusion path is locked along a line, normal to the
// specified workplane. // specified workplane.
Entity *w = SS.GetEntity(predef.entityB); Entity *w = SK.GetEntity(predef.entityB);
ExprVector u = w->Normal()->NormalExprsU(); ExprVector u = w->Normal()->NormalExprsU();
ExprVector v = w->Normal()->NormalExprsV(); ExprVector v = w->Normal()->NormalExprsV();
ExprVector extruden = { ExprVector extruden = {
@ -504,7 +504,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
} }
} else if(type == TRANSLATE) { } else if(type == TRANSLATE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) { 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 n = w->Normal()->NormalExprsN();
ExprVector trans; ExprVector trans;
trans = ExprVector::From(h.param(0), h.param(1), h.param(2)); 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) { void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
Entity *ep = SS.GetEntity(in); Entity *ep = SK.GetEntity(in);
Entity en; Entity en;
ZERO(&en); ZERO(&en);
@ -558,8 +558,8 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
} else if(ep->type == Entity::LINE_SEGMENT) { } else if(ep->type == Entity::LINE_SEGMENT) {
// A line gets extruded to form a plane face; an endpoint of the // 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. // original line is a point in the plane, and the line is in the plane.
Vector a = SS.GetEntity(ep->point[0])->PointGetNum(); Vector a = SK.GetEntity(ep->point[0])->PointGetNum();
Vector b = SS.GetEntity(ep->point[1])->PointGetNum(); Vector b = SK.GetEntity(ep->point[1])->PointGetNum();
Vector ab = b.Minus(a); Vector ab = b.Minus(a);
en.param[0] = h.param(0); 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) void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
{ {
if(pt.v == 0) return; if(pt.v == 0) return;
Group *src = SS.GetGroup(opA); Group *src = SK.GetGroup(opA);
Vector n = src->poly.normal; Vector n = src->poly.normal;
Entity en; Entity en;
@ -742,13 +742,13 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
void Group::TagEdgesFromLineSegments(SEdgeList *el) { void Group::TagEdgesFromLineSegments(SEdgeList *el) {
int i, j; int i, j;
for(i = 0; i < SS.entity.n; i++) { for(i = 0; i < SK.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]); Entity *e = &(SK.entity.elem[i]);
if(e->group.v != opA.v) continue; if(e->group.v != opA.v) continue;
if(e->type != Entity::LINE_SEGMENT) continue; if(e->type != Entity::LINE_SEGMENT) continue;
Vector p0 = SS.GetEntity(e->point[0])->PointGetNum(); Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
Vector p1 = SS.GetEntity(e->point[1])->PointGetNum(); Vector p1 = SK.GetEntity(e->point[1])->PointGetNum();
for(j = 0; j < el->l.n; j++) { for(j = 0; j < el->l.n; j++) {
SEdge *se = &(el->l.elem[j]); SEdge *se = &(el->l.elem[j]);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,8 +40,8 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
UndoState *ut = &(uk->d[uk->write]); UndoState *ut = &(uk->d[uk->write]);
ZERO(ut); ZERO(ut);
for(i = 0; i < group.n; i++) { for(i = 0; i < SK.group.n; i++) {
Group *src = &(group.elem[i]); Group *src = &(SK.group.elem[i]);
Group dest = *src; Group dest = *src;
// And then clean up all the stuff that needs to be a deep copy, // 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. // and zero out all the dynamic stuff that will get regenerated.
@ -62,17 +62,17 @@ void SolveSpace::PushFromCurrentOnto(UndoStack *uk) {
ZERO(&(dest.impEntity)); ZERO(&(dest.impEntity));
ut->group.Add(&dest); ut->group.Add(&dest);
} }
for(i = 0; i < request.n; i++) { for(i = 0; i < SK.request.n; i++) {
ut->request.Add(&(request.elem[i])); ut->request.Add(&(SK.request.elem[i]));
} }
for(i = 0; i < constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
Constraint *src = &(constraint.elem[i]); Constraint *src = &(SK.constraint.elem[i]);
Constraint dest = *src; Constraint dest = *src;
ZERO(&(dest.dogd)); ZERO(&(dest.dogd));
ut->constraint.Add(&dest); ut->constraint.Add(&dest);
} }
for(i = 0; i < param.n; i++) { for(i = 0; i < SK.param.n; i++) {
ut->param.Add(&(param.elem[i])); ut->param.Add(&(SK.param.elem[i]));
} }
ut->activeGroup = SS.GW.activeGroup; ut->activeGroup = SS.GW.activeGroup;
@ -88,8 +88,8 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
int i; int i;
// Free everything in the main copy of the program before replacing it // Free everything in the main copy of the program before replacing it
for(i = 0; i < group.n; i++) { for(i = 0; i < SK.group.n; i++) {
Group *g = &(group.elem[i]); Group *g = &(SK.group.elem[i]);
g->poly.Clear(); g->poly.Clear();
g->bezierLoopSet.Clear(); g->bezierLoopSet.Clear();
g->runningMesh.Clear(); g->runningMesh.Clear();
@ -100,16 +100,16 @@ void SolveSpace::PopOntoCurrentFrom(UndoStack *uk) {
g->impMesh.Clear(); g->impMesh.Clear();
g->impEntity.Clear(); g->impEntity.Clear();
} }
group.Clear(); SK.group.Clear();
request.Clear(); SK.request.Clear();
constraint.Clear(); SK.constraint.Clear();
param.Clear(); SK.param.Clear();
// And then do a shallow copy of the state from the undo list // And then do a shallow copy of the state from the undo list
ut->group.MoveSelfInto(&group); ut->group.MoveSelfInto(&(SK.group));
ut->request.MoveSelfInto(&request); ut->request.MoveSelfInto(&(SK.request));
ut->constraint.MoveSelfInto(&constraint); ut->constraint.MoveSelfInto(&(SK.constraint));
ut->param.MoveSelfInto(&param); ut->param.MoveSelfInto(&(SK.param));
SS.GW.activeGroup = ut->activeGroup; SS.GW.activeGroup = ut->activeGroup;
// No need to free it, since a shallow copy was made above // 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 Quaternion::From(hParam w, hParam vx, hParam vy, hParam vz) {
Quaternion q; Quaternion q;
q.w = SS.GetParam(w )->val; q.w = SK.GetParam(w )->val;
q.vx = SS.GetParam(vx)->val; q.vx = SK.GetParam(vx)->val;
q.vy = SS.GetParam(vy)->val; q.vy = SK.GetParam(vy)->val;
q.vz = SS.GetParam(vz)->val; q.vz = SK.GetParam(vz)->val;
return q; 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 Vector::From(hParam x, hParam y, hParam z) {
Vector v; Vector v;
v.x = SS.GetParam(x)->val; v.x = SK.GetParam(x)->val;
v.y = SS.GetParam(y)->val; v.y = SK.GetParam(y)->val;
v.z = SS.GetParam(z)->val; v.z = SK.GetParam(z)->val;
return v; return v;
} }
@ -504,7 +504,7 @@ Vector Vector::WithMagnitude(double v) {
} }
Vector Vector::ProjectVectorInto(hEntity wrkpl) { Vector Vector::ProjectVectorInto(hEntity wrkpl) {
Entity *w = SS.GetEntity(wrkpl); Entity *w = SK.GetEntity(wrkpl);
Vector u = w->Normal()->NormalU(); Vector u = w->Normal()->NormalU();
Vector v = w->Normal()->NormalV(); Vector v = w->Normal()->NormalV();
@ -515,7 +515,7 @@ Vector Vector::ProjectVectorInto(hEntity wrkpl) {
} }
Vector Vector::ProjectInto(hEntity wrkpl) { Vector Vector::ProjectInto(hEntity wrkpl) {
Entity *w = SS.GetEntity(wrkpl); Entity *w = SK.GetEntity(wrkpl);
Vector p0 = w->WorkplaneGetOffset(); Vector p0 = w->WorkplaneGetOffset();
Vector f = this->Minus(p0); Vector f = this->Minus(p0);