Add option to mirror imported geometry, including the shell, mesh,

and parametric entities. Also consolidate the text screen functions
to change group options into a single function for everything.

[git-p4: depot-paths = "//depot/solvespace/": change = 2051]
This commit is contained in:
Jonathan Westhues 2009-10-09 04:57:10 -08:00
parent ce37b1cf72
commit c153e23f49
15 changed files with 146 additions and 105 deletions

1
dsc.h
View File

@ -39,6 +39,7 @@ public:
Quaternion ToThe(double p); Quaternion ToThe(double p);
Quaternion Inverse(void); Quaternion Inverse(void);
Quaternion Times(Quaternion b); Quaternion Times(Quaternion b);
Quaternion MirrorZ(void);
}; };
class Vector { class Vector {

View File

@ -93,6 +93,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
{ 'g', "Group.visible", 'b', &(SS.sv.g.visible) }, { 'g', "Group.visible", 'b', &(SS.sv.g.visible) },
{ 'g', "Group.suppress", 'b', &(SS.sv.g.suppress) }, { 'g', "Group.suppress", 'b', &(SS.sv.g.suppress) },
{ 'g', "Group.relaxConstraints", 'b', &(SS.sv.g.relaxConstraints) }, { 'g', "Group.relaxConstraints", 'b', &(SS.sv.g.relaxConstraints) },
{ 'g', "Group.mirror", 'b', &(SS.sv.g.mirror) },
{ 'g', "Group.remap", 'M', &(SS.sv.g.remap) }, { 'g', "Group.remap", 'M', &(SS.sv.g.remap) },
{ 'g', "Group.impFile", 'P', &(SS.sv.g.impFile) }, { 'g', "Group.impFile", 'P', &(SS.sv.g.impFile) },
{ 'g', "Group.impFileRel", 'P', &(SS.sv.g.impFileRel) }, { 'g', "Group.impFileRel", 'P', &(SS.sv.g.impFileRel) },

View File

@ -706,6 +706,7 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.param[6] = qvz; en.param[6] = qvz;
} }
en.numPoint = ep->actPoint; en.numPoint = ep->actPoint;
if(mirror) en.numPoint.z *= -1;
break; break;
case Entity::NORMAL_N_COPY: case Entity::NORMAL_N_COPY:
@ -727,6 +728,8 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.param[3] = qvz; en.param[3] = qvz;
} }
en.numNormal = ep->actNormal; en.numNormal = ep->actNormal;
if(mirror) en.numNormal = en.numNormal.MirrorZ();
en.point[0] = Remap(ep->point[0], remap); en.point[0] = Remap(ep->point[0], remap);
break; break;
@ -762,6 +765,11 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
} }
en.numPoint = ep->actPoint; en.numPoint = ep->actPoint;
en.numNormal = ep->actNormal; en.numNormal = ep->actNormal;
if(mirror) {
if(en.type != Entity::FACE_N_ROT_TRANS) oops();
en.numPoint.z *= -1;
en.numNormal.vz *= -1;
}
break; break;
default: default:

View File

@ -95,7 +95,8 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
if(type == TRANSLATE) { if(type == TRANSLATE) {
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));
trans = trans.ScaledBy(ap); trans = trans.ScaledBy(ap);
transd.MakeFromTransformationOf(steps, trans, Quaternion::IDENTITY); transd.MakeFromTransformationOf(steps,
trans, Quaternion::IDENTITY, false);
} 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 * SK.GetParam(h.param(3))->val; double theta = ap * SK.GetParam(h.param(3))->val;
@ -104,7 +105,7 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
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);
// Rotation is centered at t; so A(x - t) + t = Ax + (t - At) // Rotation is centered at t; so A(x - t) + t = Ax + (t - At)
transd.MakeFromTransformationOf(steps, transd.MakeFromTransformationOf(steps,
trans.Minus(q.Rotate(trans)), q); trans.Minus(q.Rotate(trans)), q, false);
} }
// We need to rewrite any plane face entities to the transformed ones. // We need to rewrite any plane face entities to the transformed ones.
@ -247,10 +248,10 @@ void Group::GenerateShellAndMesh(void) {
SK.GetParam(h.param(5))->val, SK.GetParam(h.param(5))->val,
SK.GetParam(h.param(6))->val }; SK.GetParam(h.param(6))->val };
thisMesh.MakeFromTransformationOf(&impMesh, offset, q); thisMesh.MakeFromTransformationOf(&impMesh, offset, q, mirror);
thisMesh.RemapFaces(this, 0); thisMesh.RemapFaces(this, 0);
thisShell.MakeFromTransformationOf(&impShell, offset, q); thisShell.MakeFromTransformationOf(&impShell, offset, q, mirror);
thisShell.RemapFaces(this, 0); thisShell.RemapFaces(this, 0);
} }

View File

@ -293,10 +293,19 @@ void SMesh::MakeFromAssemblyOf(SMesh *a, SMesh *b) {
MakeFromCopyOf(b); MakeFromCopyOf(b);
} }
void SMesh::MakeFromTransformationOf(SMesh *a, Vector trans, Quaternion q) { void SMesh::MakeFromTransformationOf(SMesh *a, Vector trans, Quaternion q,
bool mirror)
{
STriangle *tr; STriangle *tr;
for(tr = a->l.First(); tr; tr = a->l.NextAfter(tr)) { for(tr = a->l.First(); tr; tr = a->l.NextAfter(tr)) {
STriangle tt = *tr; STriangle tt = *tr;
if(mirror) {
tt.a.z *= -1;
tt.b.z *= -1;
tt.c.z *= -1;
// The mirroring would otherwise turn a closed mesh inside out.
SWAP(Vector, tt.a, tt.b);
}
tt.a = (q.Rotate(tt.a)).Plus(trans); tt.a = (q.Rotate(tt.a)).Plus(trans);
tt.b = (q.Rotate(tt.b)).Plus(trans); tt.b = (q.Rotate(tt.b)).Plus(trans);
tt.c = (q.Rotate(tt.c)).Plus(trans); tt.c = (q.Rotate(tt.c)).Plus(trans);

View File

@ -204,7 +204,8 @@ public:
void MakeFromDifferenceOf(SMesh *a, SMesh *b); void MakeFromDifferenceOf(SMesh *a, SMesh *b);
void MakeFromCopyOf(SMesh *a); void MakeFromCopyOf(SMesh *a);
void MakeFromTransformationOf(SMesh *a, Vector trans, Quaternion q); void MakeFromTransformationOf(SMesh *a, Vector trans, Quaternion q,
bool mirror);
void MakeFromAssemblyOf(SMesh *a, SMesh *b); void MakeFromAssemblyOf(SMesh *a, SMesh *b);
void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d);

View File

@ -102,6 +102,7 @@ public:
bool visible; bool visible;
bool suppress; bool suppress;
bool relaxConstraints; bool relaxConstraints;
bool mirror;
bool clean; bool clean;
bool vvMeshClean; bool vvMeshClean;

View File

@ -687,7 +687,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
ab = (i == 0) ? a : b; ab = (i == 0) ? a : b;
for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) { for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) {
cn = SCurve::FromTransformationOf(c, t, q); cn = SCurve::FromTransformationOf(c, t, q, false);
cn.source = (i == 0) ? SCurve::FROM_A : SCurve::FROM_B; cn.source = (i == 0) ? SCurve::FROM_A : SCurve::FROM_B;
// surfA and surfB are wrong now, and we can't fix them until // surfA and surfB are wrong now, and we can't fix them until
// we've assigned IDs to the surfaces. So we'll get that later. // we've assigned IDs to the surfaces. So we'll get that later.
@ -700,7 +700,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
ab = (i == 0) ? a : b; ab = (i == 0) ? a : b;
for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) { for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) {
sn = SSurface::FromTransformationOf(s, t, q, true); sn = SSurface::FromTransformationOf(s, t, q, false, true);
// All the trim curve IDs get rewritten; we know the new handles // All the trim curve IDs get rewritten; we know the new handles
// to the curves since we recorded them in the previous step. // to the curves since we recorded them in the previous step.
STrimBy *stb; STrimBy *stb;

View File

@ -88,10 +88,11 @@ void SBezier::GetBoundingProjd(Vector u, Vector orig,
} }
} }
SBezier SBezier::TransformedBy(Vector t, Quaternion q) { SBezier SBezier::TransformedBy(Vector t, Quaternion q, bool mirror) {
SBezier ret = *this; SBezier ret = *this;
int i; int i;
for(i = 0; i <= deg; i++) { for(i = 0; i <= deg; i++) {
if(mirror) ret.ctrl[i].z *= -1;
ret.ctrl[i] = (q.Rotate(ret.ctrl[i])).Plus(t); ret.ctrl[i] = (q.Rotate(ret.ctrl[i])).Plus(t);
} }
return ret; return ret;
@ -167,7 +168,7 @@ SBezier SBezier::InPerspective(Vector u, Vector v, Vector n,
Quaternion q = Quaternion::From(u, v); Quaternion q = Quaternion::From(u, v);
q = q.Inverse(); q = q.Inverse();
// we want Q*(p - o) = Q*p - Q*o // we want Q*(p - o) = Q*p - Q*o
SBezier ret = this->TransformedBy(q.Rotate(origin).ScaledBy(-1), q); SBezier ret = this->TransformedBy(q.Rotate(origin).ScaledBy(-1), q, false);
int i; int i;
for(i = 0; i <= deg; i++) { for(i = 0; i <= deg; i++) {
Vector4 ct = Vector4::From(ret.weight[i], ret.ctrl[i]); Vector4 ct = Vector4::From(ret.weight[i], ret.ctrl[i]);
@ -427,20 +428,23 @@ void SBezierLoopSet::Clear(void) {
l.Clear(); l.Clear();
} }
SCurve SCurve::FromTransformationOf(SCurve *a, Vector t, Quaternion q) { SCurve SCurve::FromTransformationOf(SCurve *a, Vector t, Quaternion q,
bool mirror)
{
SCurve ret; SCurve ret;
ZERO(&ret); ZERO(&ret);
ret.h = a->h; ret.h = a->h;
ret.isExact = a->isExact; ret.isExact = a->isExact;
ret.exact = (a->exact).TransformedBy(t, q); ret.exact = (a->exact).TransformedBy(t, q, mirror);
ret.surfA = a->surfA; ret.surfA = a->surfA;
ret.surfB = a->surfB; ret.surfB = a->surfB;
SCurvePt *p; SCurvePt *p;
for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) { for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) {
SCurvePt pp = *p; SCurvePt pp = *p;
pp.p = (q.Rotate(p->p)).Plus(t); if(mirror) pp.p.z *= -1;
pp.p = (q.Rotate(pp.p)).Plus(t);
ret.pts.Add(&pp); ret.pts.Add(&pp);
} }
return ret; return ret;

View File

@ -133,6 +133,7 @@ SSurface SSurface::FromPlane(Vector pt, Vector u, Vector v) {
} }
SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q, SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q,
bool mirror,
bool includingTrims) bool includingTrims)
{ {
SSurface ret; SSurface ret;
@ -147,7 +148,10 @@ SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q,
int i, j; int i, j;
for(i = 0; i <= 3; i++) { for(i = 0; i <= 3; i++) {
for(j = 0; j <= 3; j++) { for(j = 0; j <= 3; j++) {
ret.ctrl[i][j] = (q.Rotate(a->ctrl[i][j])).Plus(t); ret.ctrl[i][j] = a->ctrl[i][j];
if(mirror) ret.ctrl[i][j].z *= -1;
ret.ctrl[i][j] = (q.Rotate(ret.ctrl[i][j])).Plus(t);
ret.weight[i][j] = a->weight[i][j]; ret.weight[i][j] = a->weight[i][j];
} }
} }
@ -156,12 +160,22 @@ SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q,
STrimBy *stb; STrimBy *stb;
for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) { for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) {
STrimBy n = *stb; STrimBy n = *stb;
if(mirror) {
n.start.z *= -1;
n.finish.z *= -1;
}
n.start = (q.Rotate(n.start)) .Plus(t); n.start = (q.Rotate(n.start)) .Plus(t);
n.finish = (q.Rotate(n.finish)).Plus(t); n.finish = (q.Rotate(n.finish)).Plus(t);
ret.trim.Add(&n); ret.trim.Add(&n);
} }
} }
if(mirror) {
// If we mirror every surface of a shell, then it will end up inside
// out. So fix that here.
ret.Reverse();
}
return ret; return ret;
} }
@ -522,7 +536,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
SCurve sc; SCurve sc;
ZERO(&sc); ZERO(&sc);
sc.isExact = true; sc.isExact = true;
sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY); sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY, false);
(sc.exact).MakePwlInto(&(sc.pts)); (sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = hs0; sc.surfA = hs0;
sc.surfB = hsext; sc.surfB = hsext;
@ -530,7 +544,7 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
ZERO(&sc); ZERO(&sc);
sc.isExact = true; sc.isExact = true;
sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY); sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY, false);
(sc.exact).MakePwlInto(&(sc.pts)); (sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = hs1; sc.surfA = hs1;
sc.surfB = hsext; sc.surfB = hsext;
@ -669,7 +683,7 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
if(revs.d[j].v) { if(revs.d[j].v) {
ZERO(&sc); ZERO(&sc);
sc.isExact = true; sc.isExact = true;
sc.exact = sb->TransformedBy(ts, qs); sc.exact = sb->TransformedBy(ts, qs, false);
(sc.exact).MakePwlInto(&(sc.pts)); (sc.exact).MakePwlInto(&(sc.pts));
sc.surfA = revs.d[j]; sc.surfA = revs.d[j];
sc.surfB = revs.d[WRAP(j-1, 4)]; sc.surfB = revs.d[WRAP(j-1, 4)];
@ -795,23 +809,26 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
} }
void SShell::MakeFromCopyOf(SShell *a) { void SShell::MakeFromCopyOf(SShell *a) {
MakeFromTransformationOf(a, Vector::From(0, 0, 0), Quaternion::IDENTITY); MakeFromTransformationOf(a,
Vector::From(0, 0, 0), Quaternion::IDENTITY, false);
} }
void SShell::MakeFromTransformationOf(SShell *a, Vector t, Quaternion q) { void SShell::MakeFromTransformationOf(SShell *a,
Vector t, Quaternion q, bool mirror)
{
booleanFailed = false; booleanFailed = false;
SSurface *s; SSurface *s;
for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) { for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) {
SSurface n; SSurface n;
n = SSurface::FromTransformationOf(s, t, q, true); n = SSurface::FromTransformationOf(s, t, q, mirror, true);
surface.Add(&n); // keeping the old ID surface.Add(&n); // keeping the old ID
} }
SCurve *c; SCurve *c;
for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) { for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) {
SCurve n; SCurve n;
n = SCurve::FromTransformationOf(c, t, q); n = SCurve::FromTransformationOf(c, t, q, mirror);
curve.Add(&n); // keeping the old ID curve.Add(&n); // keeping the old ID
} }
} }

View File

@ -89,7 +89,7 @@ public:
bool IsCircle(Vector axis, Vector *center, double *r); bool IsCircle(Vector axis, Vector *center, double *r);
bool IsRational(void); bool IsRational(void);
SBezier TransformedBy(Vector t, Quaternion q); SBezier TransformedBy(Vector t, Quaternion q, bool mirror);
SBezier InPerspective(Vector u, Vector v, Vector n, SBezier InPerspective(Vector u, Vector v, Vector n,
Vector origin, double cameraTan); Vector origin, double cameraTan);
@ -166,7 +166,8 @@ public:
hSSurface surfA; hSSurface surfA;
hSSurface surfB; hSSurface surfB;
static SCurve FromTransformationOf(SCurve *a, Vector t, Quaternion q); static SCurve FromTransformationOf(SCurve *a, Vector t, Quaternion q,
bool mirror);
SCurve MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, SCurve MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
SSurface *srfA, SSurface *srfB); SSurface *srfA, SSurface *srfB);
void RemoveShortSegments(SSurface *srfA, SSurface *srfB); void RemoveShortSegments(SSurface *srfA, SSurface *srfB);
@ -236,6 +237,7 @@ public:
double thetas, double thetaf); double thetas, double thetaf);
static SSurface FromPlane(Vector pt, Vector u, Vector v); static SSurface FromPlane(Vector pt, Vector u, Vector v);
static SSurface FromTransformationOf(SSurface *a, Vector t, Quaternion q, static SSurface FromTransformationOf(SSurface *a, Vector t, Quaternion q,
bool mirror,
bool includingTrims); bool includingTrims);
void EdgeNormalsWithinSurface(Point2d auv, Point2d buv, void EdgeNormalsWithinSurface(Point2d auv, Point2d buv,
@ -358,7 +360,8 @@ public:
Vector edge_n_in, Vector edge_n_out, Vector surf_n); Vector edge_n_in, Vector edge_n_out, Vector surf_n);
void MakeFromCopyOf(SShell *a); void MakeFromCopyOf(SShell *a);
void MakeFromTransformationOf(SShell *a, Vector trans, Quaternion q); void MakeFromTransformationOf(SShell *a, Vector trans, Quaternion q,
bool mirror);
void MakeFromAssemblyOf(SShell *a, SShell *b); void MakeFromAssemblyOf(SShell *a, SShell *b);
void MergeCoincidentSurfaces(void); void MergeCoincidentSurfaces(void);

View File

@ -203,64 +203,51 @@ void TextWindow::ScreenSelectRequest(int link, DWORD v) {
SS.GW.ClearSelection(); SS.GW.ClearSelection();
SS.GW.selection[0].entity = hr.entity(0); SS.GW.selection[0].entity = hr.entity(0);
} }
void TextWindow::ScreenChangeOneOrTwoSides(int link, DWORD v) {
SS.UndoRemember();
void TextWindow::ScreenChangeGroupOption(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
switch(link) {
case 's':
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 {
g->subtype = Group::ONE_SIDED; g->subtype = Group::ONE_SIDED;
} else oops(); }
SS.MarkGroupDirty(g->h); break;
SS.GenerateAll();
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeSkipFirst(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group); case 'k':
(g->skipFirst) = !(g->skipFirst); (g->skipFirst) = !(g->skipFirst);
SS.MarkGroupDirty(g->h); break;
SS.GenerateAll();
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group); case 'c':
g->meshCombine = v; g->meshCombine = v;
SS.MarkGroupDirty(g->h); break;
SS.GenerateAll();
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeMeshOrExact(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group); case 'P':
g->forceToMesh = !(g->forceToMesh);
SS.MarkGroupDirty(g->h);
SS.GenerateAll();
SS.GW.ClearSuper();
}
void TextWindow::ScreenChangeSuppress(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group);
g->suppress = !(g->suppress); g->suppress = !(g->suppress);
break;
case 'm':
g->mirror = !(g->mirror);
break;
case 'r':
g->relaxConstraints = !(g->relaxConstraints);
break;
case 'f':
g->forceToMesh = !(g->forceToMesh);
break;
}
SS.MarkGroupDirty(g->h); SS.MarkGroupDirty(g->h);
SS.GenerateAll(); SS.GenerateAll();
SS.GW.ClearSuper(); SS.GW.ClearSuper();
} }
void TextWindow::ScreenChangeRelaxConstraints(int link, DWORD v) {
SS.UndoRemember();
Group *g = SK.GetGroup(SS.TW.shown.group);
g->relaxConstraints = !(g->relaxConstraints);
SS.MarkGroupDirty(g->h);
SS.later.generateAll = true;
SS.later.showTW = true;
}
void TextWindow::ScreenChangeRightLeftHanded(int link, DWORD v) { void TextWindow::ScreenChangeRightLeftHanded(int link, DWORD v) {
SS.UndoRemember(); SS.UndoRemember();
@ -367,10 +354,10 @@ void TextWindow::ShowGroupInfo(void) {
g->type == Group::TRANSLATE) g->type == Group::TRANSLATE)
{ {
bool one = (g->subtype == Group::ONE_SIDED); bool one = (g->subtype == Group::ONE_SIDED);
Printf(true, "%Ft%s%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", s, Printf(true, "%Ft%s%E %Fh%f%Ls%s%E%Fs%s%E / %Fh%f%Ls%s%E%Fs%s%E", s,
&TextWindow::ScreenChangeOneOrTwoSides, &TextWindow::ScreenChangeGroupOption,
(one ? "" : "one side"), (one ? "one side" : ""), (one ? "" : "one side"), (one ? "one side" : ""),
&TextWindow::ScreenChangeOneOrTwoSides, &TextWindow::ScreenChangeGroupOption,
(!one ? "" : "two sides"), (!one ? "two sides" : "")); (!one ? "" : "two sides"), (!one ? "two sides" : ""));
} }
@ -402,11 +389,11 @@ void TextWindow::ShowGroupInfo(void) {
bool space; bool space;
if(g->subtype == Group::ONE_SIDED) { if(g->subtype == Group::ONE_SIDED) {
bool skip = g->skipFirst; bool skip = g->skipFirst;
Printf(true, "%Ft%s%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", Printf(true, "%Ft%s%E %Fh%f%Lk%s%E%Fs%s%E / %Fh%f%Lk%s%E%Fs%s%E",
s3, s3,
&ScreenChangeSkipFirst, &ScreenChangeGroupOption,
(!skip ? "" : "with original"), (!skip ? "with original" : ""), (!skip ? "" : "with original"), (!skip ? "with original" : ""),
&ScreenChangeSkipFirst, &ScreenChangeGroupOption,
(skip ? "":"with copy #1"), (skip ? "with copy #1":"")); (skip ? "":"with copy #1"), (skip ? "with copy #1":""));
space = false; space = false;
} else { } else {
@ -435,34 +422,40 @@ void TextWindow::ShowGroupInfo(void) {
bool asa = (g->type == Group::IMPORTED); bool asa = (g->type == Group::IMPORTED);
Printf((g->type == Group::HELICAL_SWEEP), Printf((g->type == Group::HELICAL_SWEEP),
"%FtMERGE AS%E %Fh%f%D%Ll%s%E%Fs%s%E / %Fh%f%D%Ll%s%E%Fs%s%E %s " "%FtMERGE AS%E %Fh%f%D%Lc%s%E%Fs%s%E / %Fh%f%D%Lc%s%E%Fs%s%E %s "
"%Fh%f%D%Ll%s%E%Fs%s%E", "%Fh%f%D%Lc%s%E%Fs%s%E",
&TextWindow::ScreenChangeMeshCombine, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_UNION, Group::COMBINE_AS_UNION,
(un ? "" : "union"), (un ? "union" : ""), (un ? "" : "union"), (un ? "union" : ""),
&TextWindow::ScreenChangeMeshCombine, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_DIFFERENCE, Group::COMBINE_AS_DIFFERENCE,
(diff ? "" : "difference"), (diff ? "difference" : ""), (diff ? "" : "difference"), (diff ? "difference" : ""),
asa ? "/" : "", asa ? "/" : "",
&TextWindow::ScreenChangeMeshCombine, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_ASSEMBLE, Group::COMBINE_AS_ASSEMBLE,
(asy || !asa ? "" : "assemble"), (asy && asa ? "assemble" : "")); (asy || !asa ? "" : "assemble"), (asy && asa ? "assemble" : ""));
} }
if(g->type == Group::IMPORTED) { if(g->type == Group::IMPORTED) {
bool sup = g->suppress; bool sup = g->suppress;
Printf(false, "%FtSUPPRESS%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", Printf(false, "%FtSUPPRESS%E %Fh%f%LP%s%E%Fs%s%E / %Fh%f%LP%s%E%Fs%s%E",
&TextWindow::ScreenChangeSuppress, &TextWindow::ScreenChangeGroupOption,
(sup ? "" : "yes"), (sup ? "yes" : ""), (sup ? "" : "yes"), (sup ? "yes" : ""),
&TextWindow::ScreenChangeSuppress, &TextWindow::ScreenChangeGroupOption,
(!sup ? "" : "no"), (!sup ? "no" : "")); (!sup ? "" : "no"), (!sup ? "no" : ""));
Printf(false, "%FtMIRROR%E %Fh%f%Lm%s%E%Fs%s%E / %Fh%f%Lm%s%E%Fs%s%E",
&TextWindow::ScreenChangeGroupOption,
(g->mirror ? "" : "yes"), (g->mirror ? "yes" : ""),
&TextWindow::ScreenChangeGroupOption,
(!g->mirror ? "" : "no"), (!g->mirror ? "no" : ""));
} }
bool relax = g->relaxConstraints; bool relax = g->relaxConstraints;
Printf(true, "%FtSOLVING%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", Printf(true, "%FtSOLVING%E %Fh%f%Lr%s%E%Fs%s%E / %Fh%f%Lr%s%E%Fs%s%E",
&TextWindow::ScreenChangeRelaxConstraints, &TextWindow::ScreenChangeGroupOption,
(!relax ? "" : "with all constraints"), (!relax ? "" : "with all constraints"),
(!relax ? "with all constraints" : ""), (!relax ? "with all constraints" : ""),
&TextWindow::ScreenChangeRelaxConstraints, &TextWindow::ScreenChangeGroupOption,
(relax ? "" : "no"), (relax ? "no" : "")); (relax ? "" : "no"), (relax ? "no" : ""));
if(g->type == Group::EXTRUDE || if(g->type == Group::EXTRUDE ||
@ -490,10 +483,10 @@ void TextWindow::ShowGroupInfo(void) {
if(pg->runningMesh.IsEmpty() && g->thisMesh.IsEmpty()) { if(pg->runningMesh.IsEmpty() && g->thisMesh.IsEmpty()) {
bool fm = g->forceToMesh; bool fm = g->forceToMesh;
Printf(true, Printf(true,
"%FtSURFACES%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E", "%FtSURFACES%E %Fh%f%Lf%s%E%Fs%s%E / %Fh%f%Lf%s%E%Fs%s%E",
&TextWindow::ScreenChangeMeshOrExact, &TextWindow::ScreenChangeGroupOption,
(!fm ? "" : "as NURBS"), (!fm ? "as NURBS" : ""), (!fm ? "" : "as NURBS"), (!fm ? "as NURBS" : ""),
&TextWindow::ScreenChangeMeshOrExact, &TextWindow::ScreenChangeGroupOption,
(fm ? "" : "as mesh"), (fm ? "as mesh" : "")); (fm ? "" : "as mesh"), (fm ? "as mesh" : ""));
} else { } else {
Printf(false, Printf(false,

7
ui.h
View File

@ -147,12 +147,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 ScreenChangeOneOrTwoSides(int link, DWORD v); static void ScreenChangeGroupOption(int link, DWORD v);
static void ScreenChangeSkipFirst(int link, DWORD v);
static void ScreenChangeMeshCombine(int link, DWORD v);
static void ScreenChangeMeshOrExact(int link, DWORD v);
static void ScreenChangeSuppress(int link, DWORD v);
static void ScreenChangeRelaxConstraints(int link, DWORD v);
static void ScreenChangeRightLeftHanded(int link, DWORD v); static void ScreenChangeRightLeftHanded(int link, DWORD v);
static void ScreenChangeHelixParameter(int link, DWORD v); static void ScreenChangeHelixParameter(int link, DWORD v);
static void ScreenColor(int link, DWORD v); static void ScreenColor(int link, DWORD v);

View File

@ -290,6 +290,14 @@ Quaternion Quaternion::Times(Quaternion b) {
return r; return r;
} }
Quaternion Quaternion::MirrorZ(void) {
Vector u = RotationU(),
v = RotationV();
u.z *= -1;
v.z *= -1;
return Quaternion::From(u, v);
}
Vector Vector::From(double x, double y, double z) { Vector Vector::From(double x, double y, double z) {
Vector v; Vector v;

View File

@ -2,17 +2,16 @@
multi-drag multi-drag
copy and paste copy and paste
wireframe export wireframe export
import mirrored interpolating splines
associative entities from solid model, as a special group
----- -----
some kind of import some kind of import
filled contours for export filled contours for export
faster triangulation faster triangulation
interpolating splines
loop detection loop detection
IGES export IGES export
incremental regen of entities incremental regen of entities
associative entities from solid model, as a special group
rounding, as a special group rounding, as a special group