Add user interface to specify union/difference for extrudes, and
implement that. Also make solver work only between the first and last visible group; earlier can just work from previous solve result, and later don't matter. There's some issues with the csg code; it will eventually produce an open mesh, which is very bad. Not sure whether that's a logic bug, or a numerical issue; still generating absurd triangles pretty routinely. [git-p4: depot-paths = "//depot/solvespace/": change = 1741]
This commit is contained in:
parent
1909d4c520
commit
248f74547e
|
@ -276,7 +276,7 @@ void Constraint::MenuConstrain(int id) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_SOLVE_NOW:
|
case GraphicsWindow::MNU_SOLVE_NOW:
|
||||||
SS.GenerateAll(true);
|
SS.GenerateAll(true, 0, 10000);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_SOLVE_AUTO:
|
case GraphicsWindow::MNU_SOLVE_AUTO:
|
||||||
|
|
|
@ -83,7 +83,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
Vector gu = SS.GW.projUp.ScaledBy(1/SS.GW.scale);
|
Vector gu = SS.GW.projUp.ScaledBy(1/SS.GW.scale);
|
||||||
Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale);
|
Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale);
|
||||||
|
|
||||||
glxColor3d(1, 0.2, 1);
|
glxColor3d(1, 0.4, 1);
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case PT_PT_DISTANCE: {
|
case PT_PT_DISTANCE: {
|
||||||
Vector ap = SS.GetEntity(ptA)->PointGetNum();
|
Vector ap = SS.GetEntity(ptA)->PointGetNum();
|
||||||
|
|
1
file.cpp
1
file.cpp
|
@ -51,6 +51,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
||||||
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
||||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||||
|
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
||||||
{ 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) },
|
{ 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) },
|
||||||
{ 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) },
|
{ 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) },
|
||||||
{ 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) },
|
{ 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) },
|
||||||
|
|
|
@ -102,12 +102,19 @@ void GraphicsWindow::Init(void) {
|
||||||
projRight.x = 1; projRight.y = projRight.z = 0;
|
projRight.x = 1; projRight.y = projRight.z = 0;
|
||||||
projUp.y = 1; projUp.z = projUp.x = 0;
|
projUp.y = 1; projUp.z = projUp.x = 0;
|
||||||
|
|
||||||
EnsureValidActives();
|
|
||||||
|
|
||||||
// Start locked on to the XY plane.
|
// Start locked on to the XY plane.
|
||||||
hRequest r = Request::HREQUEST_REFERENCE_XY;
|
hRequest r = Request::HREQUEST_REFERENCE_XY;
|
||||||
activeWorkplane = r.entity(0);
|
activeWorkplane = r.entity(0);
|
||||||
|
|
||||||
|
// And with the latest visible group active
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < SS.group.n; i++) {
|
||||||
|
Group *g = &(SS.group.elem[i]);
|
||||||
|
if(g->visible) activeGroup = g->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureValidActives();
|
||||||
|
|
||||||
showWorkplanes = true;
|
showWorkplanes = true;
|
||||||
showNormals = true;
|
showNormals = true;
|
||||||
showPoints = true;
|
showPoints = true;
|
||||||
|
@ -1144,11 +1151,10 @@ void GraphicsWindow::Paint(int w, int h) {
|
||||||
glxUnlockColor();
|
glxUnlockColor();
|
||||||
|
|
||||||
int i, a;
|
int i, a;
|
||||||
// Draw the groups; this fills the polygons, if requested.
|
// Draw the groups; this fills the polygons in a drawing group, and
|
||||||
|
// draws the solid mesh.
|
||||||
if(showSolids) {
|
if(showSolids) {
|
||||||
for(i = 0; i < SS.group.n; i++) {
|
(SS.GetGroup(activeGroup))->Draw();
|
||||||
SS.group.elem[i].Draw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, draw the entire scene. We don't necessarily want to draw
|
// First, draw the entire scene. We don't necessarily want to draw
|
||||||
|
@ -1180,35 +1186,5 @@ void GraphicsWindow::Paint(int w, int h) {
|
||||||
for(i = 0; i < MAX_SELECTED; i++) {
|
for(i = 0; i < MAX_SELECTED; i++) {
|
||||||
selection[i].Draw();
|
selection[i].Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SS.group.n >= 5) {
|
|
||||||
SMesh *ma = &(SS.group.elem[2].mesh);
|
|
||||||
SMesh *mb = &(SS.group.elem[4].mesh);
|
|
||||||
|
|
||||||
SBsp3 *pa = SBsp3::FromMesh(ma);
|
|
||||||
SBsp3 *pb = SBsp3::FromMesh(mb);
|
|
||||||
|
|
||||||
SMesh br; ZERO(&br);
|
|
||||||
br.flipNormal = true;
|
|
||||||
br.keepCoplanar = false;
|
|
||||||
br.AddAgainstBsp(mb, pa);
|
|
||||||
|
|
||||||
br.flipNormal = false;
|
|
||||||
br.keepCoplanar = false;
|
|
||||||
br.AddAgainstBsp(ma, pb);
|
|
||||||
|
|
||||||
dbp("triangles in = %d %d out = %d", ma->l.n, mb->l.n, br.l.n);
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glEnable(GL_LIGHTING);
|
|
||||||
glxFillMesh(&br);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
glxLockColorTo(0, 1, 0);
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glxDebugMesh(&br);
|
|
||||||
|
|
||||||
br.Clear();
|
|
||||||
FreeAllTemporary();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
mesh.cpp
28
mesh.cpp
|
@ -51,6 +51,7 @@ void SMesh::GetBounding(Vector *vmax, Vector *vmin) {
|
||||||
|
|
||||||
void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
|
void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < srcm->l.n; i++) {
|
for(i = 0; i < srcm->l.n; i++) {
|
||||||
STriangle *st = &(srcm->l.elem[i]);
|
STriangle *st = &(srcm->l.elem[i]);
|
||||||
int pn = l.n;
|
int pn = l.n;
|
||||||
|
@ -68,6 +69,32 @@ void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMesh::MakeFromUnion(SMesh *a, SMesh *b) {
|
||||||
|
SBsp3 *bspa = SBsp3::FromMesh(a);
|
||||||
|
SBsp3 *bspb = SBsp3::FromMesh(b);
|
||||||
|
|
||||||
|
flipNormal = false;
|
||||||
|
keepCoplanar = false;
|
||||||
|
AddAgainstBsp(b, bspa);
|
||||||
|
|
||||||
|
flipNormal = false;
|
||||||
|
keepCoplanar = true;
|
||||||
|
AddAgainstBsp(a, bspb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMesh::MakeFromDifference(SMesh *a, SMesh *b) {
|
||||||
|
SBsp3 *bspa = SBsp3::FromMesh(a);
|
||||||
|
SBsp3 *bspb = SBsp3::FromMesh(b);
|
||||||
|
|
||||||
|
flipNormal = true;
|
||||||
|
keepCoplanar = false;
|
||||||
|
AddAgainstBsp(b, bspa);
|
||||||
|
|
||||||
|
flipNormal = false;
|
||||||
|
keepCoplanar = false;
|
||||||
|
AddAgainstBsp(a, bspb);
|
||||||
|
}
|
||||||
|
|
||||||
SBsp2 *SBsp2::Alloc(void) { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); }
|
SBsp2 *SBsp2::Alloc(void) { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); }
|
||||||
SBsp3 *SBsp3::Alloc(void) { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); }
|
SBsp3 *SBsp3::Alloc(void) { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); }
|
||||||
|
|
||||||
|
@ -153,7 +180,6 @@ alt:
|
||||||
} else {
|
} else {
|
||||||
// I suppose this actually is allowed to happen, if the coplanar
|
// I suppose this actually is allowed to happen, if the coplanar
|
||||||
// face is the leaf, and all of its neighbors are earlier in tree?
|
// face is the leaf, and all of its neighbors are earlier in tree?
|
||||||
dbp("insert in plane");
|
|
||||||
InsertInPlane(false, tr, instead);
|
InsertInPlane(false, tr, instead);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -178,6 +178,8 @@ public:
|
||||||
void GetBounding(Vector *vmax, Vector *vmin);
|
void GetBounding(Vector *vmax, Vector *vmin);
|
||||||
|
|
||||||
void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3);
|
void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3);
|
||||||
|
void MakeFromUnion(SMesh *a, SMesh *b);
|
||||||
|
void MakeFromDifference(SMesh *a, SMesh *b);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
77
sketch.cpp
77
sketch.cpp
|
@ -381,15 +381,27 @@ void Group::CopyEntity(hEntity in, int a, hParam dx, hParam dy, hParam dz,
|
||||||
SS.entity.Add(&en);
|
SS.entity.Add(&en);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::MakePolygons(void) {
|
SMesh *Group::PreviousGroupMesh(void) {
|
||||||
int i;
|
int i;
|
||||||
|
for(i = 0; i < SS.group.n; i++) {
|
||||||
|
Group *g = &(SS.group.elem[i]);
|
||||||
|
if(g->h.v == h.v) break;
|
||||||
|
}
|
||||||
|
if(i == 0 || i >= SS.group.n) oops();
|
||||||
|
return &(SS.group.elem[i-1].mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::MakePolygons(void) {
|
||||||
poly.Clear();
|
poly.Clear();
|
||||||
mesh.Clear();
|
|
||||||
|
|
||||||
SEdgeList edges;
|
SEdgeList edges;
|
||||||
ZERO(&edges);
|
ZERO(&edges);
|
||||||
|
SMesh outm;
|
||||||
|
ZERO(&outm);
|
||||||
|
|
||||||
if(type == DRAWING_3D || type == DRAWING_WORKPLANE) {
|
if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
|
||||||
|
type == ROTATE || type == TRANSLATE)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SS.entity.n; i++) {
|
for(i = 0; i < SS.entity.n; i++) {
|
||||||
Entity *e = &(SS.entity.elem[i]);
|
Entity *e = &(SS.entity.elem[i]);
|
||||||
|
@ -427,7 +439,6 @@ void Group::MakePolygons(void) {
|
||||||
SMesh srcm; ZERO(&srcm);
|
SMesh srcm; ZERO(&srcm);
|
||||||
(src->poly).TriangulateInto(&srcm);
|
(src->poly).TriangulateInto(&srcm);
|
||||||
|
|
||||||
SMesh outm; ZERO(&outm);
|
|
||||||
// Do the bottom; that has normal pointing opposite from translate
|
// Do the bottom; that has normal pointing opposite from translate
|
||||||
for(i = 0; i < srcm.l.n; i++) {
|
for(i = 0; i < srcm.l.n; i++) {
|
||||||
STriangle *st = &(srcm.l.elem[i]);
|
STriangle *st = &(srcm.l.elem[i]);
|
||||||
|
@ -435,9 +446,9 @@ void Group::MakePolygons(void) {
|
||||||
bt = (st->b).Plus(tbot),
|
bt = (st->b).Plus(tbot),
|
||||||
ct = (st->c).Plus(tbot);
|
ct = (st->c).Plus(tbot);
|
||||||
if(flipBottom) {
|
if(flipBottom) {
|
||||||
mesh.AddTriangle(ct, bt, at);
|
outm.AddTriangle(ct, bt, at);
|
||||||
} else {
|
} else {
|
||||||
mesh.AddTriangle(at, bt, ct);
|
outm.AddTriangle(at, bt, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// And the top; that has the normal pointing the same dir as translate
|
// And the top; that has the normal pointing the same dir as translate
|
||||||
|
@ -447,9 +458,9 @@ void Group::MakePolygons(void) {
|
||||||
bt = (st->b).Plus(ttop),
|
bt = (st->b).Plus(ttop),
|
||||||
ct = (st->c).Plus(ttop);
|
ct = (st->c).Plus(ttop);
|
||||||
if(flipBottom) {
|
if(flipBottom) {
|
||||||
mesh.AddTriangle(at, bt, ct);
|
outm.AddTriangle(at, bt, ct);
|
||||||
} else {
|
} else {
|
||||||
mesh.AddTriangle(ct, bt, at);
|
outm.AddTriangle(ct, bt, at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srcm.Clear();
|
srcm.Clear();
|
||||||
|
@ -463,26 +474,50 @@ void Group::MakePolygons(void) {
|
||||||
Vector abot = (edge->a).Plus(tbot), bbot = (edge->b).Plus(tbot);
|
Vector abot = (edge->a).Plus(tbot), bbot = (edge->b).Plus(tbot);
|
||||||
Vector atop = (edge->a).Plus(ttop), btop = (edge->b).Plus(ttop);
|
Vector atop = (edge->a).Plus(ttop), btop = (edge->b).Plus(ttop);
|
||||||
if(flipBottom) {
|
if(flipBottom) {
|
||||||
mesh.AddTriangle(bbot, abot, atop);
|
outm.AddTriangle(bbot, abot, atop);
|
||||||
mesh.AddTriangle(bbot, atop, btop);
|
outm.AddTriangle(bbot, atop, btop);
|
||||||
} else {
|
} else {
|
||||||
mesh.AddTriangle(abot, bbot, atop);
|
outm.AddTriangle(abot, bbot, atop);
|
||||||
mesh.AddTriangle(bbot, btop, atop);
|
outm.AddTriangle(bbot, btop, atop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edges.Clear();
|
edges.Clear();
|
||||||
|
|
||||||
|
// So our group's mesh appears in outm. Combine this with the previous
|
||||||
|
// group's mesh, using the requested operation.
|
||||||
|
mesh.Clear();
|
||||||
|
SMesh *a = PreviousGroupMesh();
|
||||||
|
if(meshCombine == COMBINE_AS_UNION) {
|
||||||
|
mesh.MakeFromUnion(a, &outm);
|
||||||
|
} else {
|
||||||
|
mesh.MakeFromDifference(a, &outm);
|
||||||
|
}
|
||||||
|
outm.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::Draw(void) {
|
void Group::Draw(void) {
|
||||||
if(!visible) return;
|
// Show this even if the group is not visible. It's already possible
|
||||||
|
// to show or hide just this with the "show solids" flag.
|
||||||
|
|
||||||
|
if(type == DRAWING_3D || type == DRAWING_WORKPLANE) {
|
||||||
GLfloat mpf[] = { 0.4f, 0.4f, 0.4f, 1.0 };
|
GLfloat mpf[] = { 0.1f, 0.1f, 0.1f, 1.0 };
|
||||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mpf);
|
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mpf);
|
||||||
|
} else {
|
||||||
|
GLfloat mpf[] = { 0.3f, 0.3f, 0.3f, 1.0 };
|
||||||
|
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mpf);
|
||||||
|
}
|
||||||
|
// The back faces are drawn in red; should never seem them, since we
|
||||||
|
// draw closed shells, so that's a debugging aid.
|
||||||
GLfloat mpb[] = { 1.0f, 0.1f, 0.1f, 1.0 };
|
GLfloat mpb[] = { 1.0f, 0.1f, 0.1f, 1.0 };
|
||||||
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, mpb);
|
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, mpb);
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glxFillMesh(&mesh);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
// glxDebugMesh(&mesh);
|
||||||
|
|
||||||
if(polyError.yes) {
|
if(polyError.yes) {
|
||||||
glxColor4d(1, 0, 0, 0.2);
|
glxColor4d(1, 0, 0, 0.2);
|
||||||
glLineWidth(10);
|
glLineWidth(10);
|
||||||
|
@ -498,13 +533,11 @@ void Group::Draw(void) {
|
||||||
glxWriteText("not closed contour!");
|
glxWriteText("not closed contour!");
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
} else {
|
} else {
|
||||||
// glxFillPolygon(&poly);
|
glxColor4d(0, 1.0, 1.0, 0.1);
|
||||||
|
glPolygonOffset(-1, -1);
|
||||||
|
glxFillPolygon(&poly);
|
||||||
|
glPolygonOffset(0, 0);
|
||||||
}
|
}
|
||||||
glEnable(GL_LIGHTING);
|
|
||||||
// glxFillMesh(&mesh);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
|
|
||||||
// glxDebugMesh(&mesh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hParam Request::AddParam(IdList<Param,hParam> *param, hParam hp) {
|
hParam Request::AddParam(IdList<Param,hParam> *param, hParam hp) {
|
||||||
|
|
7
sketch.h
7
sketch.h
|
@ -84,8 +84,6 @@ public:
|
||||||
static const int TRANSLATE = 5030;
|
static const int TRANSLATE = 5030;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
bool solved;
|
|
||||||
|
|
||||||
hGroup opA;
|
hGroup opA;
|
||||||
hGroup opB;
|
hGroup opB;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
@ -113,6 +111,10 @@ public:
|
||||||
} polyError;
|
} polyError;
|
||||||
SMesh mesh;
|
SMesh mesh;
|
||||||
|
|
||||||
|
static const int COMBINE_AS_UNION = 0;
|
||||||
|
static const int COMBINE_AS_DIFFERENCE = 1;
|
||||||
|
int meshCombine;
|
||||||
|
|
||||||
NameStr name;
|
NameStr name;
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
|
|
||||||
|
@ -131,6 +133,7 @@ public:
|
||||||
|
|
||||||
void GenerateEquations(IdList<Equation,hEquation> *l);
|
void GenerateEquations(IdList<Equation,hEquation> *l);
|
||||||
|
|
||||||
|
SMesh *PreviousGroupMesh(void);
|
||||||
void MakePolygons(void);
|
void MakePolygons(void);
|
||||||
void Draw(void);
|
void Draw(void);
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@ void SolveSpace::Init(char *cmdLine) {
|
||||||
LoadFromFile(cmdLine);
|
LoadFromFile(cmdLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GenerateAll(false, 0, INT_MAX);
|
||||||
|
|
||||||
TW.Init();
|
TW.Init();
|
||||||
GW.Init();
|
GW.Init();
|
||||||
|
|
||||||
GenerateAll(false);
|
|
||||||
|
|
||||||
TW.Show();
|
TW.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,21 @@ bool SolveSpace::PruneConstraints(hGroup hg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpace::GenerateAll(bool andSolve) {
|
void SolveSpace::GenerateAll(bool andSolve) {
|
||||||
|
int i;
|
||||||
|
int firstShown = INT_MAX, lastShown = 0;
|
||||||
|
// The references don't count, so start from group 1
|
||||||
|
for(i = 1; i < group.n; i++) {
|
||||||
|
if(group.elem[i].visible) {
|
||||||
|
firstShown = min(firstShown, i);
|
||||||
|
lastShown = max(lastShown, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Even if nothing is shown, we have to keep going; the entities get
|
||||||
|
// generated for hidden groups, even though they're not solved.
|
||||||
|
GenerateAll(andSolve, firstShown, lastShown);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SolveSpace::GenerateAll(bool andSolve, int first, int last) {
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
while(PruneOrphans())
|
while(PruneOrphans())
|
||||||
|
@ -132,12 +147,6 @@ void SolveSpace::GenerateAll(bool andSolve) {
|
||||||
param.MoveSelfInto(&prev);
|
param.MoveSelfInto(&prev);
|
||||||
entity.Clear();
|
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++) {
|
for(i = 0; i < group.n; i++) {
|
||||||
Group *g = &(group.elem[i]);
|
Group *g = &(group.elem[i]);
|
||||||
|
|
||||||
|
@ -172,13 +181,24 @@ void SolveSpace::GenerateAll(bool andSolve) {
|
||||||
|
|
||||||
if(g->h.v == Group::HGROUP_REFERENCES.v) {
|
if(g->h.v == Group::HGROUP_REFERENCES.v) {
|
||||||
ForceReferences();
|
ForceReferences();
|
||||||
group.elem[0].solved = true;
|
|
||||||
} else {
|
} else {
|
||||||
// Solve this group.
|
if(i >= first && i <= last) {
|
||||||
if(andSolve) SolveGroup(g->h);
|
// The group falls inside the range, so really solve it,
|
||||||
}
|
// and then regenerate the mesh based on the solved stuff.
|
||||||
|
if(andSolve) SolveGroup(g->h);
|
||||||
|
g->MakePolygons();
|
||||||
|
} else {
|
||||||
|
// The group falls outside the range, so just assume that
|
||||||
|
// it's good wherever we left it. The mesh is unchanged,
|
||||||
|
// and the parameters must be marked as known.
|
||||||
|
for(j = 0; j < param.n; j++) {
|
||||||
|
Param *newp = &(param.elem[j]);
|
||||||
|
|
||||||
g->MakePolygons();
|
Param *prevp = prev.FindByIdNoOops(newp->h);
|
||||||
|
if(prevp) newp->known = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev.Clear();
|
prev.Clear();
|
||||||
|
@ -217,7 +237,7 @@ pruned:
|
||||||
param.Clear();
|
param.Clear();
|
||||||
prev.MoveSelfInto(¶m);
|
prev.MoveSelfInto(¶m);
|
||||||
// Try again
|
// Try again
|
||||||
GenerateAll(andSolve);
|
GenerateAll(andSolve, first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpace::ForceReferences(void) {
|
void SolveSpace::ForceReferences(void) {
|
||||||
|
@ -299,8 +319,8 @@ void SolveSpace::MenuFile(int id) {
|
||||||
case GraphicsWindow::MNU_NEW:
|
case GraphicsWindow::MNU_NEW:
|
||||||
SS.NewFile();
|
SS.NewFile();
|
||||||
SS.GenerateAll(false);
|
SS.GenerateAll(false);
|
||||||
SS.GW.Init();
|
|
||||||
SS.TW.Init();
|
SS.TW.Init();
|
||||||
|
SS.GW.Init();
|
||||||
SS.TW.Show();
|
SS.TW.Show();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,7 @@ public:
|
||||||
bool PruneConstraints(hGroup hg);
|
bool PruneConstraints(hGroup hg);
|
||||||
|
|
||||||
void GenerateAll(bool andSolve);
|
void GenerateAll(bool andSolve);
|
||||||
|
void GenerateAll(bool andSolve, int first, int last);
|
||||||
bool SolveGroup(hGroup hg);
|
bool SolveGroup(hGroup hg);
|
||||||
void ForceReferences(void);
|
void ForceReferences(void);
|
||||||
|
|
||||||
|
|
31
textwin.cpp
31
textwin.cpp
|
@ -266,6 +266,9 @@ void TextWindow::ScreenToggleGroupShown(int link, DWORD v) {
|
||||||
hGroup hg = { v };
|
hGroup hg = { v };
|
||||||
Group *g = SS.GetGroup(hg);
|
Group *g = SS.GetGroup(hg);
|
||||||
g->visible = !(g->visible);
|
g->visible = !(g->visible);
|
||||||
|
// If a group was just shown, then it might not have been generated
|
||||||
|
// previously, so regenerate.
|
||||||
|
SS.GW.GeneratePerSolving();
|
||||||
}
|
}
|
||||||
void TextWindow::ScreenShowGroupsSpecial(int link, DWORD v) {
|
void TextWindow::ScreenShowGroupsSpecial(int link, DWORD v) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -341,9 +344,19 @@ void TextWindow::ScreenChangeExtrudeSides(int link, DWORD v) {
|
||||||
Group *g = SS.GetGroup(SS.TW.shown->group);
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
if(g->subtype == Group::EXTRUDE_ONE_SIDED) {
|
if(g->subtype == Group::EXTRUDE_ONE_SIDED) {
|
||||||
g->subtype = Group::EXTRUDE_TWO_SIDED;
|
g->subtype = Group::EXTRUDE_TWO_SIDED;
|
||||||
} else {
|
} else if(g->subtype == Group::EXTRUDE_TWO_SIDED) {
|
||||||
g->subtype = Group::EXTRUDE_ONE_SIDED;
|
g->subtype = Group::EXTRUDE_ONE_SIDED;
|
||||||
}
|
} else oops();
|
||||||
|
SS.GW.GeneratePerSolving();
|
||||||
|
SS.GW.ClearSuper();
|
||||||
|
}
|
||||||
|
void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
||||||
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
|
if(g->meshCombine == Group::COMBINE_AS_DIFFERENCE) {
|
||||||
|
g->meshCombine = Group::COMBINE_AS_UNION;
|
||||||
|
} else if(g->meshCombine == Group::COMBINE_AS_UNION) {
|
||||||
|
g->meshCombine = Group::COMBINE_AS_DIFFERENCE;
|
||||||
|
} else oops();
|
||||||
SS.GW.GeneratePerSolving();
|
SS.GW.GeneratePerSolving();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
}
|
}
|
||||||
|
@ -361,12 +374,18 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE) {
|
if(g->type == Group::EXTRUDE) {
|
||||||
bool one = (g->subtype == Group::EXTRUDE_ONE_SIDED);
|
bool one = (g->subtype == Group::EXTRUDE_ONE_SIDED);
|
||||||
Printf(true, "%FtEXTRUDE%E one-sided: %Fh%f%Ll%s%E%Fs%s%E",
|
Printf(true, "%FtEXTRUDE%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
||||||
&TextWindow::ScreenChangeExtrudeSides,
|
&TextWindow::ScreenChangeExtrudeSides,
|
||||||
(one ? "" : "no"), (one ? "yes" : ""));
|
(one ? "" : "one side"), (one ? "one-side" : ""),
|
||||||
Printf(false, " two-sided: %Fh%f%Ll%s%E%Fs%s%E",
|
|
||||||
&TextWindow::ScreenChangeExtrudeSides,
|
&TextWindow::ScreenChangeExtrudeSides,
|
||||||
(!one ? "" : "no"), (!one ? "yes" : ""));
|
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
||||||
|
|
||||||
|
bool diff = (g->meshCombine == Group::COMBINE_AS_DIFFERENCE);
|
||||||
|
Printf(false, "%FtCOMBINE%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
||||||
|
&TextWindow::ScreenChangeMeshCombine,
|
||||||
|
(!diff ? "" : "as union"), (!diff ? "as union" : ""),
|
||||||
|
&TextWindow::ScreenChangeMeshCombine,
|
||||||
|
(diff ? "" : "as difference"), (diff ? "as difference" : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(true, "%Ftrequests in group");
|
Printf(true, "%Ftrequests in group");
|
||||||
|
|
1
ui.h
1
ui.h
|
@ -74,6 +74,7 @@ public:
|
||||||
static void ScreenSelectRequest(int link, DWORD v);
|
static void ScreenSelectRequest(int link, DWORD v);
|
||||||
static void ScreenSelectConstraint(int link, DWORD v);
|
static void ScreenSelectConstraint(int link, DWORD v);
|
||||||
static void ScreenChangeExtrudeSides(int link, DWORD v);
|
static void ScreenChangeExtrudeSides(int link, DWORD v);
|
||||||
|
static void ScreenChangeMeshCombine(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenNavigation(int link, DWORD v);
|
static void ScreenNavigation(int link, DWORD v);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user