
vectors", represented by unit quaternions. This permits me to add circles, where the normal defines the plane of the circle. Still many things painful. The interface for editing normals is not so intuitive, and it's not yet clear how I would e.g. export a circle entity and recreate it properly, since that entity has a param not associated with a normal or point. And the transformed points/normals do not yet support rotations. That will be necessary soon. [git-p4: depot-paths = "//depot/solvespace/": change = 1705]
162 lines
4.3 KiB
C++
162 lines
4.3 KiB
C++
#include "solvespace.h"
|
|
|
|
SolveSpace SS;
|
|
|
|
void SolveSpace::Init(char *cmdLine) {
|
|
if(strlen(cmdLine) == 0) {
|
|
NewFile();
|
|
} else {
|
|
LoadFromFile(cmdLine);
|
|
}
|
|
|
|
TW.Init();
|
|
GW.Init();
|
|
|
|
GenerateAll(false);
|
|
|
|
TW.Show();
|
|
}
|
|
|
|
void SolveSpace::GenerateAll(bool andSolve) {
|
|
int i, j;
|
|
|
|
// Don't lose our numerical guesses when we regenerate.
|
|
IdList<Param,hParam> prev;
|
|
param.MoveSelfInto(&prev);
|
|
entity.Clear();
|
|
|
|
for(i = 0; i < group.n; i++) {
|
|
group.elem[i].solved = false;
|
|
}
|
|
|
|
// For now, solve the groups in given order; should discover the
|
|
// correct order later.
|
|
for(i = 0; i < group.n; i++) {
|
|
Group *g = &(group.elem[i]);
|
|
|
|
for(j = 0; j < request.n; j++) {
|
|
Request *r = &(request.elem[j]);
|
|
if(r->group.v != g->h.v) continue;
|
|
|
|
r->Generate(&entity, ¶m);
|
|
}
|
|
|
|
g->Generate(&entity, ¶m);
|
|
|
|
// Use the previous values for params that we've seen before, as
|
|
// initial guesses for the solver.
|
|
for(j = 0; j < param.n; j++) {
|
|
Param *newp = &(param.elem[j]);
|
|
if(newp->known) continue;
|
|
|
|
Param *prevp = prev.FindByIdNoOops(newp->h);
|
|
if(prevp) newp->val = prevp->val;
|
|
}
|
|
|
|
if(g->h.v == Group::HGROUP_REFERENCES.v) {
|
|
ForceReferences();
|
|
group.elem[0].solved = true;
|
|
} else {
|
|
// Solve this group.
|
|
if(andSolve) SolveGroup(g->h);
|
|
}
|
|
|
|
g->MakePolygons();
|
|
}
|
|
|
|
prev.Clear();
|
|
InvalidateGraphics();
|
|
}
|
|
|
|
void SolveSpace::ForceReferences(void) {
|
|
// Force the values of the paramters that define the three reference
|
|
// coordinate systems.
|
|
static const struct {
|
|
hRequest hr;
|
|
Quaternion q;
|
|
} Quat[] = {
|
|
{ Request::HREQUEST_REFERENCE_XY, { 1, 0, 0, 0, } },
|
|
{ Request::HREQUEST_REFERENCE_YZ, { 0.5, 0.5, 0.5, 0.5, } },
|
|
{ Request::HREQUEST_REFERENCE_ZX, { 0.5, -0.5, -0.5, -0.5, } },
|
|
};
|
|
for(int i = 0; i < 3; i++) {
|
|
hRequest hr = Quat[i].hr;
|
|
Entity *wrkpl = GetEntity(hr.entity(0));
|
|
// The origin for our coordinate system, always zero
|
|
Entity *origin = GetEntity(wrkpl->point[0]);
|
|
origin->PointForceTo(Vector::MakeFrom(0, 0, 0));
|
|
GetParam(origin->param[0])->known = true;
|
|
GetParam(origin->param[1])->known = true;
|
|
GetParam(origin->param[2])->known = true;
|
|
// The quaternion that defines the rotation, from the table.
|
|
Entity *normal = GetEntity(wrkpl->normal);
|
|
normal->NormalForceTo(Quat[i].q);
|
|
GetParam(normal->param[0])->known = true;
|
|
GetParam(normal->param[1])->known = true;
|
|
GetParam(normal->param[2])->known = true;
|
|
GetParam(normal->param[3])->known = true;
|
|
}
|
|
}
|
|
|
|
bool SolveSpace::SolveGroup(hGroup hg) {
|
|
int i;
|
|
// Clear out the system to be solved.
|
|
sys.entity.Clear();
|
|
sys.param.Clear();
|
|
sys.eq.Clear();
|
|
// And generate all the params for requests in this group
|
|
for(i = 0; i < request.n; i++) {
|
|
Request *r = &(request.elem[i]);
|
|
if(r->group.v != hg.v) continue;
|
|
|
|
r->Generate(&(sys.entity), &(sys.param));
|
|
}
|
|
// And for the group itself
|
|
Group *g = SS.GetGroup(hg);
|
|
g->Generate(&(sys.entity), &(sys.param));
|
|
// Set the initial guesses for all the params
|
|
for(i = 0; i < sys.param.n; i++) {
|
|
Param *p = &(sys.param.elem[i]);
|
|
p->known = false;
|
|
p->val = GetParam(p->h)->val;
|
|
}
|
|
// And generate all the equations from constraints in this group
|
|
for(i = 0; i < constraint.n; i++) {
|
|
Constraint *c = &(constraint.elem[i]);
|
|
if(c->group.v != hg.v) continue;
|
|
|
|
c->Generate(&(sys.eq));
|
|
}
|
|
|
|
bool r = sys.Solve();
|
|
FreeAllTemporary();
|
|
return r;
|
|
}
|
|
|
|
void SolveSpace::MenuFile(int id) {
|
|
switch(id) {
|
|
case GraphicsWindow::MNU_NEW:
|
|
SS.NewFile();
|
|
SS.GenerateAll(false);
|
|
SS.GW.Init();
|
|
SS.TW.Init();
|
|
SS.TW.Show();
|
|
break;
|
|
|
|
case GraphicsWindow::MNU_OPEN:
|
|
break;
|
|
|
|
case GraphicsWindow::MNU_SAVE:
|
|
SS.SaveToFile("t.slvs");
|
|
break;
|
|
|
|
case GraphicsWindow::MNU_SAVE_AS:
|
|
break;
|
|
|
|
case GraphicsWindow::MNU_EXIT:
|
|
break;
|
|
|
|
default: oops();
|
|
}
|
|
}
|