Add helical sweeps. These aren't as parametric as I would have
liked, but my more parametric attempts were very difficult to use. The pitch (both axial and radial) gets specified by typing a distance in a textbox. [git-p4: depot-paths = "//depot/solvespace/": change = 1804]
This commit is contained in:
parent
fe75efc6aa
commit
3ddd1703b1
3
draw.cpp
3
draw.cpp
|
@ -363,7 +363,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
case MNU_RECTANGLE: {
|
||||
if(!SS.GW.LockedInWorkplane()) {
|
||||
Error("Can't draw rectangle in 3d; select a workplane first.");
|
||||
break;
|
||||
ClearSuper();
|
||||
break;
|
||||
}
|
||||
hRequest lns[4];
|
||||
int i;
|
||||
|
|
2
file.cpp
2
file.cpp
|
@ -67,6 +67,8 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
|||
{ 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) },
|
||||
{ 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) },
|
||||
{ 'g', "Group.valA", 'f', &(SS.sv.g.valA) },
|
||||
{ 'g', "Group.valB", 'f', &(SS.sv.g.valB) },
|
||||
{ 'g', "Group.valC", 'f', &(SS.sv.g.valB) },
|
||||
{ 'g', "Group.color", 'x', &(SS.sv.g.color) },
|
||||
{ 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) },
|
||||
{ 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) },
|
||||
|
|
|
@ -48,6 +48,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
|||
{ 1, "E&xtrude\tShift+Ctrl+X", MNU_GROUP_EXTRUDE, 'X'|S|C,mGrp },
|
||||
{ 1, "&Lathe\tShift+Ctrl+L", MNU_GROUP_LATHE, 'L'|S|C,mGrp },
|
||||
{ 1, "&Sweep\tShift+Ctrl+S", MNU_GROUP_SWEEP, 'S'|S|C,mGrp },
|
||||
{ 1, "&Helical Sweep\tShift+Ctrl+H", MNU_GROUP_HELICAL, 'H'|S|C,mGrp },
|
||||
{ 1, NULL, 0, 0, NULL },
|
||||
{ 1, "Import / Assemble...\tShift+Ctrl+I", MNU_GROUP_IMPORT, 'I'|S|C,mGrp },
|
||||
{11, "Import Recent", MNU_GROUP_RECENT, 0, mGrp },
|
||||
|
|
36
group.cpp
36
group.cpp
|
@ -20,6 +20,7 @@ void Group::MenuGroup(int id) {
|
|||
Group g;
|
||||
ZERO(&g);
|
||||
g.visible = true;
|
||||
g.color = RGB(100, 100, 100);
|
||||
|
||||
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
||||
strcpy(g.impFile, RecentFile[id-RECENT_IMPORT]);
|
||||
|
@ -75,7 +76,6 @@ void Group::MenuGroup(int id) {
|
|||
case GraphicsWindow::MNU_GROUP_EXTRUDE:
|
||||
g.type = EXTRUDE;
|
||||
g.opA = SS.GW.activeGroup;
|
||||
g.color = RGB(100, 100, 100);
|
||||
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||
g.subtype = ONE_SIDED;
|
||||
g.name.strcpy("extrude");
|
||||
|
@ -95,7 +95,6 @@ void Group::MenuGroup(int id) {
|
|||
}
|
||||
g.type = LATHE;
|
||||
g.opA = SS.GW.activeGroup;
|
||||
g.color = RGB(100, 100, 100);
|
||||
g.name.strcpy("lathe");
|
||||
SS.GW.ClearSelection();
|
||||
break;
|
||||
|
@ -119,11 +118,38 @@ void Group::MenuGroup(int id) {
|
|||
}
|
||||
// The active group is our section
|
||||
g.opB = SS.GW.activeGroup;
|
||||
g.color = RGB(100, 100, 100);
|
||||
g.name.strcpy("sweep");
|
||||
break;
|
||||
}
|
||||
|
||||
case GraphicsWindow::MNU_GROUP_HELICAL: {
|
||||
if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) {
|
||||
Vector pt = SS.GetEntity(gs.point[0])->PointGetNum();
|
||||
Entity *ln = SS.GetEntity(gs.entity[0]);
|
||||
Vector lpa = SS.GetEntity(ln->point[0])->PointGetNum();
|
||||
Vector lpb = SS.GetEntity(ln->point[1])->PointGetNum();
|
||||
double d = pt.DistanceToLine(lpa, lpb.Minus(lpa));
|
||||
if(d < LENGTH_EPS) {
|
||||
Error("Point on helix can't lie on helix's axis!");
|
||||
return;
|
||||
}
|
||||
g.predef.origin = gs.point[0];
|
||||
g.predef.entityB = gs.entity[0];
|
||||
} else {
|
||||
Error("Bad selection for helical sweep.");
|
||||
return;
|
||||
}
|
||||
g.type = HELICAL_SWEEP;
|
||||
g.subtype = RIGHT_HANDED;
|
||||
g.valA = 3; // turns;
|
||||
g.valB = 300/SS.GW.scale; // pitch along axis
|
||||
g.valC = 0; // pitch in radius
|
||||
g.opA = SS.GW.activeGroup;
|
||||
g.name.strcpy("helical-sweep");
|
||||
SS.GW.ClearSelection();
|
||||
break;
|
||||
}
|
||||
|
||||
case GraphicsWindow::MNU_GROUP_ROT: {
|
||||
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
|
||||
g.predef.origin = gs.point[0];
|
||||
|
@ -315,6 +341,10 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||
break;
|
||||
}
|
||||
|
||||
case HELICAL_SWEEP: {
|
||||
break;
|
||||
}
|
||||
|
||||
case TRANSLATE: {
|
||||
// The translation vector
|
||||
AddParam(param, h.param(0), gp.x);
|
||||
|
|
|
@ -38,9 +38,10 @@ void Group::GeneratePolygon(void) {
|
|||
|
||||
void Group::GetTrajectory(hGroup hg, SContour *traj, SPolygon *section) {
|
||||
if(section->IsEmpty()) return;
|
||||
|
||||
|
||||
SEdgeList edges; ZERO(&edges);
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < SS.entity.n; i++) {
|
||||
Entity *e = &(SS.entity.elem[i]);
|
||||
if(e->group.v != hg.v) continue;
|
||||
|
@ -100,7 +101,6 @@ void Group::GetTrajectory(hGroup hg, SContour *traj, SPolygon *section) {
|
|||
// The starting point is the endpoint that's closer to the plane
|
||||
traj->Reverse();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
edges.Clear();
|
||||
}
|
||||
|
@ -197,20 +197,41 @@ void Group::GenerateMeshForStepAndRepeat(void) {
|
|||
thisMesh.Clear();
|
||||
}
|
||||
|
||||
void Group::GenerateMeshForSweep(void) {
|
||||
void Group::GenerateMeshForSweep(bool helical,
|
||||
Vector axisp, Vector axis, Vector onHelix)
|
||||
{
|
||||
STriMeta meta = { 0, color };
|
||||
SEdgeList edges;
|
||||
ZERO(&edges);
|
||||
int a, i;
|
||||
|
||||
// The closed section that will be swept along the curve
|
||||
Group *section = SS.GetGroup(opB);
|
||||
Group *section = SS.GetGroup(helical ? opA : opB);
|
||||
SEdgeList edges;
|
||||
ZERO(&edges);
|
||||
(section->poly).MakeEdgesInto(&edges);
|
||||
|
||||
// The trajectory along which the section will be swept
|
||||
SContour traj;
|
||||
ZERO(&traj);
|
||||
GetTrajectory(opA, &traj, &(section->poly));
|
||||
if(helical) {
|
||||
double r0 = onHelix.DistanceToLine(axisp, axis);
|
||||
int n = (int)(SS.CircleSides(r0)*valA) + 4;
|
||||
Vector origin = onHelix.ClosestPointOnLine(axisp, axis);
|
||||
Vector u = (onHelix.Minus(origin)).WithMagnitude(1);
|
||||
Vector v = (axis.Cross(u)).WithMagnitude(1);
|
||||
for(i = 0; i <= n; i++) {
|
||||
double turns = (i*valA)/n;
|
||||
double theta = turns*2*PI;
|
||||
double r = r0 + turns*valC;
|
||||
if(subtype == LEFT_HANDED) theta = -theta;
|
||||
Vector p = origin.Plus(
|
||||
u.ScaledBy(r*cos(theta)).Plus(
|
||||
v.ScaledBy(r*sin(theta)).Plus(
|
||||
axis.WithMagnitude(turns*valB))));
|
||||
traj.AddPoint(p);
|
||||
}
|
||||
} else {
|
||||
GetTrajectory(opA, &traj, &(section->poly));
|
||||
}
|
||||
|
||||
if(traj.l.n <= 0) {
|
||||
edges.Clear();
|
||||
|
@ -222,7 +243,17 @@ void Group::GenerateMeshForSweep(void) {
|
|||
Vector origNormal = (traj.l.elem[1].p).Minus(origRef);
|
||||
origNormal = origNormal.WithMagnitude(1);
|
||||
Vector oldRef = origRef, oldNormal = origNormal;
|
||||
Vector oldU = oldNormal.Normal(0), oldV = oldNormal.Normal(1);
|
||||
|
||||
Vector oldU, oldV;
|
||||
if(helical) {
|
||||
oldU = axis.WithMagnitude(1);
|
||||
oldV = (oldNormal.Cross(oldU)).WithMagnitude(1);
|
||||
// numerical fixup, since pwl segment isn't exactly tangent...
|
||||
oldU = (oldV.Cross(oldNormal)).WithMagnitude(1);
|
||||
} else {
|
||||
oldU = oldNormal.Normal(0);
|
||||
oldV = oldNormal.Normal(1);
|
||||
}
|
||||
|
||||
// The endcap at the start of the curve
|
||||
SPolygon cap;
|
||||
|
@ -257,11 +288,18 @@ void Group::GenerateMeshForSweep(void) {
|
|||
useNormal = (thisNormal.Plus(oldNormal)).ScaledBy(0.5);
|
||||
}
|
||||
|
||||
// Choose a new coordinate system, normal to the trajectory and
|
||||
// with the minimum possible twist about the normal.
|
||||
Vector useV, useU;
|
||||
useNormal = useNormal.WithMagnitude(1);
|
||||
Vector useV = (useNormal.Cross(oldU)).WithMagnitude(1);
|
||||
Vector useU = (useV.Cross(useNormal)).WithMagnitude(1);
|
||||
if(helical) {
|
||||
// The axis of rotation is always a basis vector
|
||||
useU = axis.WithMagnitude(1);
|
||||
useV = (useNormal.Cross(useU)).WithMagnitude(1);
|
||||
} else {
|
||||
// Choose a new coordinate system, normal to the trajectory and
|
||||
// with the minimum possible twist about the normal.
|
||||
useV = (useNormal.Cross(oldU)).WithMagnitude(1);
|
||||
useU = (useV.Cross(useNormal)).WithMagnitude(1);
|
||||
}
|
||||
|
||||
Quaternion qi = Quaternion::From(oldU, oldV);
|
||||
Quaternion qf = Quaternion::From(useU, useV);
|
||||
|
@ -432,7 +470,14 @@ void Group::GenerateMesh(void) {
|
|||
}
|
||||
}
|
||||
} else if(type == SWEEP) {
|
||||
GenerateMeshForSweep();
|
||||
Vector zp = Vector::From(0, 0, 0);
|
||||
GenerateMeshForSweep(false, zp, zp, zp);
|
||||
} else if(type == HELICAL_SWEEP) {
|
||||
Entity *ln = SS.GetEntity(predef.entityB);
|
||||
Vector lna = SS.GetEntity(ln->point[0])->PointGetNum(),
|
||||
lnb = SS.GetEntity(ln->point[1])->PointGetNum();
|
||||
Vector onh = SS.GetEntity(predef.origin)->PointGetNum();
|
||||
GenerateMeshForSweep(true, lna, lnb.Minus(lna), onh);
|
||||
} else if(type == IMPORTED) {
|
||||
// Triangles are just copied over, with the appropriate transformation
|
||||
// applied.
|
||||
|
|
25
sketch.h
25
sketch.h
|
@ -83,6 +83,7 @@ public:
|
|||
static const int EXTRUDE = 5100;
|
||||
static const int LATHE = 5101;
|
||||
static const int SWEEP = 5102;
|
||||
static const int HELICAL_SWEEP = 5103;
|
||||
static const int ROTATE = 5200;
|
||||
static const int TRANSLATE = 5201;
|
||||
static const int IMPORTED = 5300;
|
||||
|
@ -94,6 +95,8 @@ public:
|
|||
bool clean;
|
||||
hEntity activeWorkplane;
|
||||
double valA;
|
||||
double valB;
|
||||
double valC;
|
||||
DWORD color;
|
||||
|
||||
static const int SOLVED_OKAY = 0;
|
||||
|
@ -104,10 +107,15 @@ public:
|
|||
SList<hConstraint> remove;
|
||||
} solved;
|
||||
|
||||
// For drawings in 2d
|
||||
static const int WORKPLANE_BY_POINT_ORTHO = 6000;
|
||||
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
|
||||
// For extrudes, translates, and rotates
|
||||
static const int ONE_SIDED = 7000;
|
||||
static const int TWO_SIDED = 7001;
|
||||
// For helical sweeps
|
||||
static const int RIGHT_HANDED = 8000;
|
||||
static const int LEFT_HANDED = 8001;
|
||||
int subtype;
|
||||
|
||||
bool skipFirst; // for step and repeat ops
|
||||
|
@ -158,8 +166,8 @@ public:
|
|||
void Activate(void);
|
||||
char *DescriptionString(void);
|
||||
|
||||
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
||||
static void AddParam(ParamList *param, hParam hp, double v);
|
||||
void Generate(EntityList *entity, ParamList *param);
|
||||
// When a request generates entities from entities, and the source
|
||||
// entities may have come from multiple requests, it's necessary to
|
||||
// remap the entity ID so that it's still unique. We do this with a
|
||||
|
@ -170,10 +178,10 @@ public:
|
|||
static const int REMAP_PT_TO_LINE = 1003;
|
||||
static const int REMAP_LINE_TO_FACE = 1004;
|
||||
hEntity Remap(hEntity in, int copyNumber);
|
||||
void MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in);
|
||||
void MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt);
|
||||
void MakeExtrusionLines(EntityList *el, hEntity in);
|
||||
void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
|
||||
void TagEdgesFromLineSegments(SEdgeList *sle);
|
||||
void CopyEntity(IdList<Entity,hEntity> *el,
|
||||
void CopyEntity(EntityList *el,
|
||||
Entity *ep, int timesApplied, int remap,
|
||||
hParam dx, hParam dy, hParam dz,
|
||||
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
||||
|
@ -190,7 +198,8 @@ public:
|
|||
void AddQuadWithNormal(STriMeta meta, Vector out,
|
||||
Vector a, Vector b, Vector c, Vector d);
|
||||
void GenerateMeshForStepAndRepeat(void);
|
||||
void GenerateMeshForSweep(void);
|
||||
void GenerateMeshForSweep(bool helical,
|
||||
Vector axisp, Vector axis, Vector onHelix);
|
||||
void GenerateMesh(void);
|
||||
void Draw(void);
|
||||
|
||||
|
@ -226,8 +235,8 @@ public:
|
|||
|
||||
bool construction;
|
||||
|
||||
static hParam AddParam(IdList<Param,hParam> *param, hParam hp);
|
||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
||||
static hParam AddParam(ParamList *param, hParam hp);
|
||||
void Generate(EntityList *entity, ParamList *param);
|
||||
|
||||
char *DescriptionString(void);
|
||||
};
|
||||
|
|
|
@ -101,7 +101,10 @@ void vl(void); // debug function to validate
|
|||
|
||||
class Entity;
|
||||
class hEntity;
|
||||
class Param;
|
||||
class hParam;
|
||||
typedef IdList<Entity,hEntity> EntityList;
|
||||
typedef IdList<Param,hParam> ParamList;
|
||||
|
||||
#include "sketch.h"
|
||||
#include "ui.h"
|
||||
|
@ -144,8 +147,8 @@ class System {
|
|||
public:
|
||||
#define MAX_UNKNOWNS 200
|
||||
|
||||
IdList<Entity,hEntity> entity;
|
||||
IdList<Param,hParam> param;
|
||||
EntityList entity;
|
||||
ParamList param;
|
||||
IdList<Equation,hEquation> eq;
|
||||
|
||||
// In general, the tag indicates the subsys that a variable/equation
|
||||
|
|
93
textwin.cpp
93
textwin.cpp
|
@ -626,6 +626,39 @@ void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
|||
SS.GenerateAll();
|
||||
SS.GW.ClearSuper();
|
||||
}
|
||||
void TextWindow::ScreenChangeRightLeftHanded(int link, DWORD v) {
|
||||
SS.UndoRemember();
|
||||
|
||||
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||
if(g->subtype == Group::RIGHT_HANDED) {
|
||||
g->subtype = Group::LEFT_HANDED;
|
||||
} else {
|
||||
g->subtype = Group::RIGHT_HANDED;
|
||||
}
|
||||
SS.MarkGroupDirty(g->h);
|
||||
SS.GenerateAll();
|
||||
SS.GW.ClearSuper();
|
||||
}
|
||||
void TextWindow::ScreenChangeHelixParameter(int link, DWORD v) {
|
||||
Group *g = SS.GetGroup(SS.TW.shown->group);
|
||||
char str[1024];
|
||||
int r;
|
||||
if(link == 't') {
|
||||
sprintf(str, "%.3f", g->valA);
|
||||
SS.TW.edit.meaning = EDIT_HELIX_TURNS;
|
||||
r = 12;
|
||||
} else if(link == 'p') {
|
||||
strcpy(str, SS.MmToString(g->valB));
|
||||
SS.TW.edit.meaning = EDIT_HELIX_PITCH;
|
||||
r = 14;
|
||||
} else if(link == 'r') {
|
||||
strcpy(str, SS.MmToString(g->valC));
|
||||
SS.TW.edit.meaning = EDIT_HELIX_DRADIUS;
|
||||
r = 16;
|
||||
} else oops();
|
||||
SS.TW.edit.group.v = v;
|
||||
ShowTextEditControl(r, 9, str);
|
||||
}
|
||||
void TextWindow::ScreenColor(int link, DWORD v) {
|
||||
SS.UndoRemember();
|
||||
|
||||
|
@ -683,10 +716,6 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
g->h.v, &TextWindow::ScreenDeleteGroup);
|
||||
}
|
||||
|
||||
if(g->type == Group::IMPORTED) {
|
||||
Printf(true, "%FtIMPORT%E '%s'", g->impFile);
|
||||
}
|
||||
|
||||
if(g->type == Group::EXTRUDE) {
|
||||
s = "EXTRUDE ";
|
||||
} else if(g->type == Group::TRANSLATE) {
|
||||
|
@ -708,11 +737,32 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
(one ? "" : "one side"), (one ? "one side" : ""),
|
||||
&TextWindow::ScreenChangeOneOrTwoSides,
|
||||
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
if(g->type == Group::LATHE) {
|
||||
Printf(true, "%FtLATHE");
|
||||
}
|
||||
|
||||
|
||||
if(g->type == Group::SWEEP) {
|
||||
Printf(true, "%FtSWEEP");
|
||||
}
|
||||
|
||||
if(g->type == Group::HELICAL_SWEEP) {
|
||||
bool rh = (g->subtype == Group::RIGHT_HANDED);
|
||||
Printf(true,
|
||||
"%FtHELICAL%E %Fh%f%Ll%s%E%Fs%s%E / %Fh%f%Ll%s%E%Fs%s%E",
|
||||
&ScreenChangeRightLeftHanded,
|
||||
(rh ? "" : "right-hand"), (rh ? "right-hand" : ""),
|
||||
&ScreenChangeRightLeftHanded,
|
||||
(!rh ? "" : "left-hand"), (!rh ? "left-hand" : ""));
|
||||
Printf(false, "%FtTHROUGH%E %@ turns %Fl%Lt%D%f[change]%E",
|
||||
g->valA, g->h.v, &ScreenChangeHelixParameter);
|
||||
Printf(false, "%FtPITCH%E %s per turn %Fl%Lp%D%f[change]%E",
|
||||
SS.MmToString(g->valB), g->h.v, &ScreenChangeHelixParameter);
|
||||
Printf(false, "%FtdRADIUS%E %s per turn %Fl%Lr%D%f[change]%E",
|
||||
SS.MmToString(g->valC), g->h.v, &ScreenChangeHelixParameter);
|
||||
}
|
||||
|
||||
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
||||
bool space;
|
||||
if(g->subtype == Group::ONE_SIDED) {
|
||||
|
@ -733,10 +783,15 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
s2, times, times == 1 ? "" : "s",
|
||||
g->h.v, &TextWindow::ScreenChangeExprA);
|
||||
}
|
||||
|
||||
if(g->type == Group::IMPORTED) {
|
||||
Printf(true, "%FtIMPORT%E '%s'", g->impFile);
|
||||
}
|
||||
|
||||
if(g->type == Group::EXTRUDE ||
|
||||
g->type == Group::LATHE ||
|
||||
g->type == Group::SWEEP ||
|
||||
g->type == Group::HELICAL_SWEEP ||
|
||||
g->type == Group::IMPORTED)
|
||||
{
|
||||
bool un = (g->meshCombine == Group::COMBINE_AS_UNION);
|
||||
|
@ -744,7 +799,7 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
bool asy = (g->meshCombine == Group::COMBINE_AS_ASSEMBLE);
|
||||
bool asa = (g->type == Group::IMPORTED);
|
||||
|
||||
Printf(false,
|
||||
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 "
|
||||
"%Fh%f%D%Ll%s%E%Fs%s%E",
|
||||
&TextWindow::ScreenChangeMeshCombine,
|
||||
|
@ -764,7 +819,8 @@ void TextWindow::ShowGroupInfo(void) {
|
|||
|
||||
if(g->type == Group::EXTRUDE ||
|
||||
g->type == Group::LATHE ||
|
||||
g->type == Group::SWEEP)
|
||||
g->type == Group::SWEEP ||
|
||||
g->type == Group::HELICAL_SWEEP)
|
||||
{
|
||||
#define TWOX(v) v v
|
||||
Printf(true, "%FtM_COLOR%E " TWOX(TWOX(TWOX("%Bp%D%f%Ln %Bd%E "))),
|
||||
|
@ -997,6 +1053,27 @@ void TextWindow::EditControlDone(char *s) {
|
|||
InvalidateGraphics();
|
||||
break;
|
||||
}
|
||||
case EDIT_HELIX_TURNS:
|
||||
case EDIT_HELIX_PITCH:
|
||||
case EDIT_HELIX_DRADIUS: {
|
||||
SS.UndoRemember();
|
||||
Group *g = SS.GetGroup(edit.group);
|
||||
Expr *e = Expr::From(s);
|
||||
if(!e) {
|
||||
Error("Not a valid number or expression: '%s'", s);
|
||||
break;
|
||||
}
|
||||
if(edit.meaning == EDIT_HELIX_TURNS) {
|
||||
g->valA = min(30, fabs(e->Eval()));
|
||||
} else if(edit.meaning == EDIT_HELIX_PITCH) {
|
||||
g->valB = SS.ExprToMm(e);
|
||||
} else {
|
||||
g->valC = SS.ExprToMm(e);
|
||||
}
|
||||
SS.MarkGroupDirty(g->h);
|
||||
SS.later.generateAll = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SS.later.showTW = true;
|
||||
HideTextEditControl();
|
||||
|
|
6
ui.h
6
ui.h
|
@ -64,6 +64,9 @@ public:
|
|||
static const int EDIT_COLOR = 5;
|
||||
static const int EDIT_MESH_TOLERANCE = 6;
|
||||
static const int EDIT_CAMERA_TANGENT = 7;
|
||||
static const int EDIT_HELIX_TURNS = 8;
|
||||
static const int EDIT_HELIX_PITCH = 9;
|
||||
static const int EDIT_HELIX_DRADIUS = 10;
|
||||
struct {
|
||||
int meaning;
|
||||
int i;
|
||||
|
@ -103,6 +106,8 @@ public:
|
|||
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
||||
static void ScreenChangeSkipFirst(int link, DWORD v);
|
||||
static void ScreenChangeMeshCombine(int link, DWORD v);
|
||||
static void ScreenChangeRightLeftHanded(int link, DWORD v);
|
||||
static void ScreenChangeHelixParameter(int link, DWORD v);
|
||||
static void ScreenColor(int link, DWORD v);
|
||||
|
||||
static void ScreenShowConfiguration(int link, DWORD v);
|
||||
|
@ -164,6 +169,7 @@ public:
|
|||
MNU_GROUP_EXTRUDE,
|
||||
MNU_GROUP_LATHE,
|
||||
MNU_GROUP_SWEEP,
|
||||
MNU_GROUP_HELICAL,
|
||||
MNU_GROUP_ROT,
|
||||
MNU_GROUP_TRANS,
|
||||
MNU_GROUP_IMPORT,
|
||||
|
|
Loading…
Reference in New Issue
Block a user