Bits and pieces; option to not include original in step translates
and rotates, auto-constrain translates in active workplane, speed up remap list search with a hash table, other stuff. [git-p4: depot-paths = "//depot/solvespace/": change = 1786]solver
parent
83f741bd06
commit
8969687904
5
draw.cpp
5
draw.cpp
|
@ -548,6 +548,11 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
|
||||||
ClearSuper();
|
ClearSuper();
|
||||||
|
|
||||||
Constraint *c = SS.GetConstraint(constraintBeingEdited);
|
Constraint *c = SS.GetConstraint(constraintBeingEdited);
|
||||||
|
if(c->reference) {
|
||||||
|
// Not meaningful to edit a reference dimension
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vector p3 = c->GetLabelPos();
|
Vector p3 = c->GetLabelPos();
|
||||||
Point2d p2 = ProjectPoint(p3);
|
Point2d p2 = ProjectPoint(p3);
|
||||||
ShowGraphicsEditControl((int)p2.x, (int)p2.y, c->exprA->Print());
|
ShowGraphicsEditControl((int)p2.x, (int)p2.y, c->exprA->Print());
|
||||||
|
|
18
dsc.h
18
dsc.h
|
@ -106,15 +106,21 @@ public:
|
||||||
elem = (T *)MemRealloc(elem, elemsAllocated*sizeof(elem[0]));
|
elem = (T *)MemRealloc(elem, elemsAllocated*sizeof(elem[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int first = 0, last = n;
|
||||||
if(n == 0 || elem[n-1].h.v < t->h.v) {
|
// We know that we must insert within the closed interval [first,last]
|
||||||
i = n;
|
while(first != last) {
|
||||||
|
int mid = (first + last)/2;
|
||||||
|
H hm = elem[mid].h;
|
||||||
|
if(hm.v > t->h.v) {
|
||||||
|
last = mid;
|
||||||
|
} else if(hm.v < t->h.v) {
|
||||||
|
first = mid + 1;
|
||||||
} else {
|
} else {
|
||||||
while(i < n && elem[i].h.v < t->h.v) {
|
oops();
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i < n && elem[i].h.v == t->h.v) oops();
|
int i = first;
|
||||||
|
|
||||||
memmove(elem+i+1, elem+i, (n-i)*sizeof(elem[0]));
|
memmove(elem+i+1, elem+i, (n-i)*sizeof(elem[0]));
|
||||||
elem[i] = *t;
|
elem[i] = *t;
|
||||||
n++;
|
n++;
|
||||||
|
|
|
@ -680,6 +680,6 @@ void Entity::CalculateNumerical(void) {
|
||||||
Vector n = FaceGetNormalNum();
|
Vector n = FaceGetNormalNum();
|
||||||
numNormal = Quaternion::From(0, n.x, n.y, n.z);
|
numNormal = Quaternion::From(0, n.x, n.y, n.z);
|
||||||
}
|
}
|
||||||
visible = IsVisible();
|
actVisible = IsVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
file.cpp
3
file.cpp
|
@ -68,6 +68,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'g', "Group.exprA", 'E', &(SS.sv.g.exprA) },
|
{ 'g', "Group.exprA", 'E', &(SS.sv.g.exprA) },
|
||||||
{ 'g', "Group.color", 'x', &(SS.sv.g.color) },
|
{ 'g', "Group.color", 'x', &(SS.sv.g.color) },
|
||||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||||
|
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
||||||
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
{ 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) },
|
||||||
{ 'g', "Group.predef.q.w", 'f', &(SS.sv.g.predef.q.w) },
|
{ 'g', "Group.predef.q.w", 'f', &(SS.sv.g.predef.q.w) },
|
||||||
{ 'g', "Group.predef.q.vx", 'f', &(SS.sv.g.predef.q.vx) },
|
{ 'g', "Group.predef.q.vx", 'f', &(SS.sv.g.predef.q.vx) },
|
||||||
|
@ -94,7 +95,6 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
|
|
||||||
{ 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) },
|
{ 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) },
|
||||||
{ 'e', "Entity.type", 'd', &(SS.sv.e.type) },
|
{ 'e', "Entity.type", 'd', &(SS.sv.e.type) },
|
||||||
{ 'e', "Entity.visible", 'b', &(SS.sv.e.visible) },
|
|
||||||
{ 'e', "Entity.group.v", 'x', &(SS.sv.e.group.v) },
|
{ 'e', "Entity.group.v", 'x', &(SS.sv.e.group.v) },
|
||||||
{ 'e', "Entity.construction", 'b', &(SS.sv.e.construction) },
|
{ 'e', "Entity.construction", 'b', &(SS.sv.e.construction) },
|
||||||
{ 'e', "Entity.param[0].v", 'x', &(SS.sv.e.param[0].v) },
|
{ 'e', "Entity.param[0].v", 'x', &(SS.sv.e.param[0].v) },
|
||||||
|
@ -127,6 +127,7 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||||
{ 'e', "Entity.actNormal.vy", 'f', &(SS.sv.e.actNormal.vy) },
|
{ 'e', "Entity.actNormal.vy", 'f', &(SS.sv.e.actNormal.vy) },
|
||||||
{ 'e', "Entity.actNormal.vz", 'f', &(SS.sv.e.actNormal.vz) },
|
{ 'e', "Entity.actNormal.vz", 'f', &(SS.sv.e.actNormal.vz) },
|
||||||
{ 'e', "Entity.actDistance", 'f', &(SS.sv.e.actDistance) },
|
{ 'e', "Entity.actDistance", 'f', &(SS.sv.e.actDistance) },
|
||||||
|
{ 'e', "Entity.actVisible", 'b', &(SS.sv.e.actVisible), },
|
||||||
|
|
||||||
|
|
||||||
{ 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) },
|
{ 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) },
|
||||||
|
|
43
group.cpp
43
group.cpp
|
@ -130,6 +130,8 @@ void Group::MenuGroup(int id) {
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.exprA = Expr::From(3)->DeepCopyKeep();
|
g.exprA = Expr::From(3)->DeepCopyKeep();
|
||||||
g.subtype = ONE_SIDED;
|
g.subtype = ONE_SIDED;
|
||||||
|
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||||
|
g.activeWorkplane = SS.GW.ActiveWorkplane();
|
||||||
g.name.strcpy("translate");
|
g.name.strcpy("translate");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -294,8 +296,12 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(1), gp.y);
|
AddParam(param, h.param(1), gp.y);
|
||||||
AddParam(param, h.param(2), gp.z);
|
AddParam(param, h.param(2), gp.z);
|
||||||
|
|
||||||
int n = (int)(exprA->Eval());
|
int n = (int)(exprA->Eval()), a0 = 0;
|
||||||
for(a = 0; a < n; a++) {
|
if(subtype == ONE_SIDED && skipFirst) {
|
||||||
|
a0++; n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(a = a0; a < n; a++) {
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group.v != opA.v) continue;
|
if(e->group.v != opA.v) continue;
|
||||||
|
@ -322,8 +328,12 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
AddParam(param, h.param(5), gn.y);
|
AddParam(param, h.param(5), gn.y);
|
||||||
AddParam(param, h.param(6), gn.z);
|
AddParam(param, h.param(6), gn.z);
|
||||||
|
|
||||||
int n = (int)(exprA->Eval());
|
int n = (int)(exprA->Eval()), a0 = 0;
|
||||||
for(a = 0; a < n; a++) {
|
if(subtype == ONE_SIDED && skipFirst) {
|
||||||
|
a0++; n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(a = a0; a < n; a++) {
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group.v != opA.v) continue;
|
if(e->group.v != opA.v) continue;
|
||||||
|
@ -352,7 +362,6 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
|
|
||||||
for(i = 0; i < impEntity.n; i++) {
|
for(i = 0; i < impEntity.n; i++) {
|
||||||
Entity *ie = &(impEntity.elem[i]);
|
Entity *ie = &(impEntity.elem[i]);
|
||||||
|
|
||||||
CopyEntity(entity, ie, 0, 0,
|
CopyEntity(entity, ie, 0, 0,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
h.param(3), h.param(4), h.param(5), h.param(6),
|
h.param(3), h.param(4), h.param(5), h.param(6),
|
||||||
|
@ -408,19 +417,39 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
|
||||||
AddEq(l, u.Dot(extruden), 0);
|
AddEq(l, u.Dot(extruden), 0);
|
||||||
AddEq(l, v.Dot(extruden), 1);
|
AddEq(l, v.Dot(extruden), 1);
|
||||||
}
|
}
|
||||||
|
} else if(type == TRANSLATE) {
|
||||||
|
if(predef.entityB.v != Entity::FREE_IN_3D.v) {
|
||||||
|
Entity *w = SS.GetEntity(predef.entityB);
|
||||||
|
ExprVector n = w->Normal()->NormalExprsN();
|
||||||
|
ExprVector trans;
|
||||||
|
trans = ExprVector::From(h.param(0), h.param(1), h.param(2));
|
||||||
|
|
||||||
|
// The translation vector is parallel to the workplane
|
||||||
|
AddEq(l, trans.Dot(n), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hEntity Group::Remap(hEntity in, int copyNumber) {
|
hEntity Group::Remap(hEntity in, int copyNumber) {
|
||||||
int i;
|
// A hash table is used to accelerate the search
|
||||||
|
int hash = ((unsigned)(in.v*61 + copyNumber)) % REMAP_PRIME;
|
||||||
|
int i = remapCache[hash];
|
||||||
|
if(i >= 0 && i < remap.n) {
|
||||||
|
EntityMap *em = &(remap.elem[i]);
|
||||||
|
if(em->input.v == in.v && em->copyNumber == copyNumber) {
|
||||||
|
return h.entity(em->h.v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// but if we don't find it in the hash table, then linear search
|
||||||
for(i = 0; i < remap.n; i++) {
|
for(i = 0; i < remap.n; i++) {
|
||||||
EntityMap *em = &(remap.elem[i]);
|
EntityMap *em = &(remap.elem[i]);
|
||||||
if(em->input.v == in.v && em->copyNumber == copyNumber) {
|
if(em->input.v == in.v && em->copyNumber == copyNumber) {
|
||||||
// We already have a mapping for this entity.
|
// We already have a mapping for this entity.
|
||||||
|
remapCache[hash] = i;
|
||||||
return h.entity(em->h.v);
|
return h.entity(em->h.v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We don't have a mapping yet, so create one.
|
// And if we still don't find it, then create a new entry.
|
||||||
EntityMap em;
|
EntityMap em;
|
||||||
em.input = in;
|
em.input = in;
|
||||||
em.copyNumber = copyNumber;
|
em.copyNumber = copyNumber;
|
||||||
|
|
|
@ -18,11 +18,17 @@ void Group::GeneratePolygon(void) {
|
||||||
}
|
}
|
||||||
SEdge error;
|
SEdge error;
|
||||||
if(edges.AssemblePolygon(&poly, &error)) {
|
if(edges.AssemblePolygon(&poly, &error)) {
|
||||||
polyError.yes = false;
|
polyError.how = POLY_GOOD;
|
||||||
poly.normal = poly.ComputeNormal();
|
poly.normal = poly.ComputeNormal();
|
||||||
poly.FixContourDirections();
|
poly.FixContourDirections();
|
||||||
|
|
||||||
|
if(!poly.AllPointsInPlane(&(polyError.notCoplanarAt))) {
|
||||||
|
// The edges aren't all coplanar; so not a good polygon
|
||||||
|
polyError.how = POLY_NOT_COPLANAR;
|
||||||
|
poly.Clear();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
polyError.yes = true;
|
polyError.how = POLY_NOT_CLOSED;
|
||||||
polyError.notClosedAt = error;
|
polyError.notClosedAt = error;
|
||||||
poly.Clear();
|
poly.Clear();
|
||||||
}
|
}
|
||||||
|
@ -279,8 +285,10 @@ void Group::Draw(void) {
|
||||||
|
|
||||||
if(SS.GW.showMesh) glxDebugMesh(&mesh);
|
if(SS.GW.showMesh) glxDebugMesh(&mesh);
|
||||||
|
|
||||||
|
// And finally show the polygons too
|
||||||
if(!SS.GW.showShaded) return;
|
if(!SS.GW.showShaded) return;
|
||||||
if(polyError.yes) {
|
if(polyError.how == POLY_NOT_CLOSED) {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
glxColor4d(1, 0, 0, 0.2);
|
glxColor4d(1, 0, 0, 0.2);
|
||||||
glLineWidth(10);
|
glLineWidth(10);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
|
@ -294,6 +302,16 @@ void Group::Draw(void) {
|
||||||
glxOntoWorkplane(SS.GW.projRight, SS.GW.projUp);
|
glxOntoWorkplane(SS.GW.projRight, SS.GW.projUp);
|
||||||
glxWriteText("not closed contour!");
|
glxWriteText("not closed contour!");
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
} else if(polyError.how == POLY_NOT_COPLANAR) {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glxColor3d(1, 0, 0);
|
||||||
|
glPushMatrix();
|
||||||
|
glxTranslatev(polyError.notCoplanarAt);
|
||||||
|
glxOntoWorkplane(SS.GW.projRight, SS.GW.projUp);
|
||||||
|
glxWriteText("points not all coplanar!");
|
||||||
|
glPopMatrix();
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
} else {
|
} else {
|
||||||
glxColor4d(0, 0.1, 0.1, 0.5);
|
glxColor4d(0, 0.1, 0.1, 0.5);
|
||||||
glPolygonOffset(-1, -1);
|
glPolygonOffset(-1, -1);
|
||||||
|
|
26
polygon.cpp
26
polygon.cpp
|
@ -179,6 +179,18 @@ bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) {
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SContour::AllPointsInPlane(Vector n, double d, Vector *notCoplanarAt) {
|
||||||
|
for(int i = 0; i < l.n; i++) {
|
||||||
|
Vector p = l.elem[i].p;
|
||||||
|
double dd = n.Dot(p) - d;
|
||||||
|
if(fabs(dd) > 10*LENGTH_EPS) {
|
||||||
|
*notCoplanarAt = p;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void SContour::Reverse(void) {
|
void SContour::Reverse(void) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < (l.n / 2); i++) {
|
for(i = 0; i < (l.n / 2); i++) {
|
||||||
|
@ -263,6 +275,20 @@ void SPolygon::FixContourDirections(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SPolygon::AllPointsInPlane(Vector *notCoplanarAt) {
|
||||||
|
if(l.n == 0 || l.elem[0].l.n == 0) return true;
|
||||||
|
|
||||||
|
Vector p0 = l.elem[0].l.elem[0].p;
|
||||||
|
double d = normal.Dot(p0);
|
||||||
|
|
||||||
|
for(int i = 0; i < l.n; i++) {
|
||||||
|
if(!(l.elem[i]).AllPointsInPlane(normal, d, notCoplanarAt)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int TriMode, TriVertexCount;
|
static int TriMode, TriVertexCount;
|
||||||
static Vector Tri1, TriNMinus1, TriNMinus2;
|
static Vector Tri1, TriNMinus1, TriNMinus2;
|
||||||
static Vector TriNormal;
|
static Vector TriNormal;
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
Vector ComputeNormal(void);
|
Vector ComputeNormal(void);
|
||||||
bool IsClockwiseProjdToNormal(Vector n);
|
bool IsClockwiseProjdToNormal(Vector n);
|
||||||
bool ContainsPointProjdToNormal(Vector n, Vector p);
|
bool ContainsPointProjdToNormal(Vector n, Vector p);
|
||||||
|
bool AllPointsInPlane(Vector n, double d, Vector *notCoplanarAt);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SPolygon {
|
class SPolygon {
|
||||||
|
@ -99,6 +100,7 @@ public:
|
||||||
void FixContourDirections(void);
|
void FixContourDirections(void);
|
||||||
void TriangulateInto(SMesh *m);
|
void TriangulateInto(SMesh *m);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
|
bool AllPointsInPlane(Vector *notCoplanarAt);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
15
sketch.h
15
sketch.h
|
@ -108,6 +108,8 @@ public:
|
||||||
static const int TWO_SIDED = 7001;
|
static const int TWO_SIDED = 7001;
|
||||||
int subtype;
|
int subtype;
|
||||||
|
|
||||||
|
bool skipFirst; // for step and repeat ops
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Quaternion q;
|
Quaternion q;
|
||||||
Vector p;
|
Vector p;
|
||||||
|
@ -120,10 +122,15 @@ public:
|
||||||
} predef;
|
} predef;
|
||||||
|
|
||||||
SPolygon poly;
|
SPolygon poly;
|
||||||
|
static const int POLY_GOOD = 0;
|
||||||
|
static const int POLY_NOT_CLOSED = 1;
|
||||||
|
static const int POLY_NOT_COPLANAR = 2;
|
||||||
struct {
|
struct {
|
||||||
|
int how;
|
||||||
SEdge notClosedAt;
|
SEdge notClosedAt;
|
||||||
bool yes;
|
Vector notCoplanarAt;
|
||||||
} polyError;
|
} polyError;
|
||||||
|
|
||||||
SMesh mesh;
|
SMesh mesh;
|
||||||
struct {
|
struct {
|
||||||
SMesh interferesAt;
|
SMesh interferesAt;
|
||||||
|
@ -136,6 +143,8 @@ public:
|
||||||
int meshCombine;
|
int meshCombine;
|
||||||
|
|
||||||
IdList<EntityMap,EntityId> remap;
|
IdList<EntityMap,EntityId> remap;
|
||||||
|
static const int REMAP_PRIME = 19477;
|
||||||
|
int remapCache[REMAP_PRIME];
|
||||||
|
|
||||||
char impFile[MAX_PATH];
|
char impFile[MAX_PATH];
|
||||||
SMesh impMesh;
|
SMesh impMesh;
|
||||||
|
@ -272,8 +281,6 @@ public:
|
||||||
double numDistance;
|
double numDistance;
|
||||||
// and a bit more state that the faces need
|
// and a bit more state that the faces need
|
||||||
Vector numVector;
|
Vector numVector;
|
||||||
// and the shown state also gets saved here, for later import
|
|
||||||
bool visible;
|
|
||||||
|
|
||||||
// All points/normals/distances have their numerical value; this is
|
// All points/normals/distances have their numerical value; this is
|
||||||
// a convenience, to simplify the import/assembly code, so that the
|
// a convenience, to simplify the import/assembly code, so that the
|
||||||
|
@ -281,6 +288,8 @@ public:
|
||||||
Vector actPoint;
|
Vector actPoint;
|
||||||
Quaternion actNormal;
|
Quaternion actNormal;
|
||||||
double actDistance;
|
double actDistance;
|
||||||
|
// and the shown state also gets saved here, for later import
|
||||||
|
bool actVisible;
|
||||||
|
|
||||||
hGroup group;
|
hGroup group;
|
||||||
hEntity workplane; // or Entity::FREE_IN_3D
|
hEntity workplane; // or Entity::FREE_IN_3D
|
||||||
|
|
42
textwin.cpp
42
textwin.cpp
|
@ -560,6 +560,15 @@ void TextWindow::ScreenChangeOneOrTwoSides(int link, DWORD v) {
|
||||||
SS.GenerateAll();
|
SS.GenerateAll();
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
}
|
}
|
||||||
|
void TextWindow::ScreenChangeSkipFirst(int link, DWORD v) {
|
||||||
|
SS.UndoRemember();
|
||||||
|
|
||||||
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
|
(g->skipFirst) = !(g->skipFirst);
|
||||||
|
SS.MarkGroupDirty(g->h);
|
||||||
|
SS.GenerateAll();
|
||||||
|
SS.GW.ClearSuper();
|
||||||
|
}
|
||||||
void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
|
@ -581,7 +590,11 @@ void TextWindow::ScreenColor(int link, DWORD v) {
|
||||||
}
|
}
|
||||||
void TextWindow::ScreenChangeExprA(int link, DWORD v) {
|
void TextWindow::ScreenChangeExprA(int link, DWORD v) {
|
||||||
Group *g = SS.GetGroup(SS.TW.shown->group);
|
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||||
ShowTextEditControl(13, 10, g->exprA->Print());
|
|
||||||
|
// There's an extra line for the skipFirst parameter in one-sided groups.
|
||||||
|
int r = (g->subtype == Group::ONE_SIDED) ? 15 : 13;
|
||||||
|
|
||||||
|
ShowTextEditControl(r, 9, g->exprA->Print());
|
||||||
SS.TW.edit.meaning = EDIT_TIMES_REPEATED;
|
SS.TW.edit.meaning = EDIT_TIMES_REPEATED;
|
||||||
SS.TW.edit.group.v = v;
|
SS.TW.edit.group.v = v;
|
||||||
}
|
}
|
||||||
|
@ -608,7 +621,7 @@ void TextWindow::ScreenDeleteGroup(int link, DWORD v) {
|
||||||
}
|
}
|
||||||
void TextWindow::ShowGroupInfo(void) {
|
void TextWindow::ShowGroupInfo(void) {
|
||||||
Group *g = SS.group.FindById(shown->group);
|
Group *g = SS.group.FindById(shown->group);
|
||||||
char *s, *s2;
|
char *s, *s2, *s3;
|
||||||
|
|
||||||
if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
if(shown->group.v == Group::HGROUP_REFERENCES.v) {
|
||||||
Printf(true, "%FtGROUP %E%s", g->DescriptionString());
|
Printf(true, "%FtGROUP %E%s", g->DescriptionString());
|
||||||
|
@ -629,9 +642,11 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
} else if(g->type == Group::TRANSLATE) {
|
} else if(g->type == Group::TRANSLATE) {
|
||||||
s = "TRANSLATE";
|
s = "TRANSLATE";
|
||||||
s2 ="REPEAT ";
|
s2 ="REPEAT ";
|
||||||
|
s3 ="START ";
|
||||||
} else if(g->type == Group::ROTATE) {
|
} else if(g->type == Group::ROTATE) {
|
||||||
s = "ROTATE ";
|
s = "ROTATE ";
|
||||||
s2 ="REPEAT ";
|
s2 ="REPEAT ";
|
||||||
|
s3 ="START ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE || g->type == Group::ROTATE ||
|
if(g->type == Group::EXTRUDE || g->type == Group::ROTATE ||
|
||||||
|
@ -649,8 +664,22 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
||||||
|
bool space;
|
||||||
|
if(g->subtype == Group::ONE_SIDED) {
|
||||||
|
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",
|
||||||
|
s3,
|
||||||
|
&ScreenChangeSkipFirst,
|
||||||
|
(!skip ? "" : "with original"), (!skip ? "with original" : ""),
|
||||||
|
&ScreenChangeSkipFirst,
|
||||||
|
(skip ? "":"with copy #1"), (skip ? "with copy #1":""));
|
||||||
|
space = false;
|
||||||
|
} else {
|
||||||
|
space = true;
|
||||||
|
}
|
||||||
|
|
||||||
int times = (int)(g->exprA->Eval());
|
int times = (int)(g->exprA->Eval());
|
||||||
Printf(true, "%Ft%s%E %d time%s %Fl%Ll%D%f[change]%E",
|
Printf(space, "%Ft%s%E %d time%s %Fl%Ll%D%f[change]%E",
|
||||||
s2, times, times == 1 ? "" : "s",
|
s2, times, times == 1 ? "" : "s",
|
||||||
g->h.v, &TextWindow::ScreenChangeExprA);
|
g->h.v, &TextWindow::ScreenChangeExprA);
|
||||||
}
|
}
|
||||||
|
@ -695,7 +724,14 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
0x80000000 | SS.modelColor[7], 7, &TextWindow::ScreenColor);
|
0x80000000 | SS.modelColor[7], 7, &TextWindow::ScreenColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leave more space if the group has configuration stuff above the req/
|
||||||
|
// constraint list (as all but the drawing groups do).
|
||||||
|
if(g->type == Group::DRAWING_3D || g->type == Group::DRAWING_WORKPLANE) {
|
||||||
Printf(true, "%Ftrequests in group");
|
Printf(true, "%Ftrequests in group");
|
||||||
|
} else {
|
||||||
|
Printf(false, "");
|
||||||
|
Printf(false, "%Ftrequests in group");
|
||||||
|
}
|
||||||
|
|
||||||
int i, a = 0;
|
int i, a = 0;
|
||||||
for(i = 0; i < SS.request.n; i++) {
|
for(i = 0; i < SS.request.n; i++) {
|
||||||
|
|
1
ui.h
1
ui.h
|
@ -100,6 +100,7 @@ public:
|
||||||
static void ScreenUnselectAll(int link, DWORD v);
|
static void ScreenUnselectAll(int link, DWORD v);
|
||||||
|
|
||||||
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
||||||
|
static void ScreenChangeSkipFirst(int link, DWORD v);
|
||||||
static void ScreenChangeMeshCombine(int link, DWORD v);
|
static void ScreenChangeMeshCombine(int link, DWORD v);
|
||||||
static void ScreenColor(int link, DWORD v);
|
static void ScreenColor(int link, DWORD v);
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
|
|
||||||
STL check for meshes, and T intersection removal
|
STL check for meshes, and T intersection removal
|
||||||
STL export
|
STL export
|
||||||
better triangle combining (Simplify()) for meshes
|
|
||||||
DXF export
|
DXF export
|
||||||
compress file format (binary?)
|
|
||||||
partitioned subsystems in the solver
|
partitioned subsystems in the solver
|
||||||
TTF font text
|
TTF font text
|
||||||
display with proper formatting/units
|
display with proper formatting/units
|
||||||
more measurements
|
more measurements
|
||||||
some kind of rounding / chamfer
|
some kind of rounding / chamfer
|
||||||
auto-constrain translate in then-active workplane
|
|
||||||
remove back button in browser?
|
remove back button in browser?
|
||||||
|
clean up user-created workplanes
|
||||||
|
incremental regen of entities?
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue