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
1
draw.cpp
1
draw.cpp
|
@ -363,6 +363,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
case MNU_RECTANGLE: {
|
case MNU_RECTANGLE: {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Can't draw rectangle in 3d; select a workplane first.");
|
Error("Can't draw rectangle in 3d; select a workplane first.");
|
||||||
|
ClearSuper();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hRequest lns[4];
|
hRequest lns[4];
|
||||||
|
|
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.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.valA", 'f', &(SS.sv.g.valA) },
|
{ '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.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.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, "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, "&Lathe\tShift+Ctrl+L", MNU_GROUP_LATHE, 'L'|S|C,mGrp },
|
||||||
{ 1, "&Sweep\tShift+Ctrl+S", MNU_GROUP_SWEEP, 'S'|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, NULL, 0, 0, NULL },
|
||||||
{ 1, "Import / Assemble...\tShift+Ctrl+I", MNU_GROUP_IMPORT, 'I'|S|C,mGrp },
|
{ 1, "Import / Assemble...\tShift+Ctrl+I", MNU_GROUP_IMPORT, 'I'|S|C,mGrp },
|
||||||
{11, "Import Recent", MNU_GROUP_RECENT, 0, 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;
|
Group g;
|
||||||
ZERO(&g);
|
ZERO(&g);
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
|
g.color = RGB(100, 100, 100);
|
||||||
|
|
||||||
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
if(id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT)) {
|
||||||
strcpy(g.impFile, RecentFile[id-RECENT_IMPORT]);
|
strcpy(g.impFile, RecentFile[id-RECENT_IMPORT]);
|
||||||
|
@ -75,7 +76,6 @@ void Group::MenuGroup(int id) {
|
||||||
case GraphicsWindow::MNU_GROUP_EXTRUDE:
|
case GraphicsWindow::MNU_GROUP_EXTRUDE:
|
||||||
g.type = EXTRUDE;
|
g.type = EXTRUDE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.color = RGB(100, 100, 100);
|
|
||||||
g.predef.entityB = SS.GW.ActiveWorkplane();
|
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||||
g.subtype = ONE_SIDED;
|
g.subtype = ONE_SIDED;
|
||||||
g.name.strcpy("extrude");
|
g.name.strcpy("extrude");
|
||||||
|
@ -95,7 +95,6 @@ void Group::MenuGroup(int id) {
|
||||||
}
|
}
|
||||||
g.type = LATHE;
|
g.type = LATHE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.color = RGB(100, 100, 100);
|
|
||||||
g.name.strcpy("lathe");
|
g.name.strcpy("lathe");
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
break;
|
break;
|
||||||
|
@ -119,11 +118,38 @@ void Group::MenuGroup(int id) {
|
||||||
}
|
}
|
||||||
// The active group is our section
|
// The active group is our section
|
||||||
g.opB = SS.GW.activeGroup;
|
g.opB = SS.GW.activeGroup;
|
||||||
g.color = RGB(100, 100, 100);
|
|
||||||
g.name.strcpy("sweep");
|
g.name.strcpy("sweep");
|
||||||
break;
|
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: {
|
case GraphicsWindow::MNU_GROUP_ROT: {
|
||||||
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
|
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
|
||||||
g.predef.origin = gs.point[0];
|
g.predef.origin = gs.point[0];
|
||||||
|
@ -315,6 +341,10 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case HELICAL_SWEEP: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case TRANSLATE: {
|
case TRANSLATE: {
|
||||||
// The translation vector
|
// The translation vector
|
||||||
AddParam(param, h.param(0), gp.x);
|
AddParam(param, h.param(0), gp.x);
|
||||||
|
|
|
@ -41,6 +41,7 @@ void Group::GetTrajectory(hGroup hg, SContour *traj, SPolygon *section) {
|
||||||
|
|
||||||
SEdgeList edges; ZERO(&edges);
|
SEdgeList edges; ZERO(&edges);
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
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]);
|
||||||
if(e->group.v != hg.v) continue;
|
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
|
// The starting point is the endpoint that's closer to the plane
|
||||||
traj->Reverse();
|
traj->Reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
edges.Clear();
|
edges.Clear();
|
||||||
}
|
}
|
||||||
|
@ -197,20 +197,41 @@ void Group::GenerateMeshForStepAndRepeat(void) {
|
||||||
thisMesh.Clear();
|
thisMesh.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::GenerateMeshForSweep(void) {
|
void Group::GenerateMeshForSweep(bool helical,
|
||||||
|
Vector axisp, Vector axis, Vector onHelix)
|
||||||
|
{
|
||||||
STriMeta meta = { 0, color };
|
STriMeta meta = { 0, color };
|
||||||
SEdgeList edges;
|
|
||||||
ZERO(&edges);
|
|
||||||
int a, i;
|
int a, i;
|
||||||
|
|
||||||
// The closed section that will be swept along the curve
|
// 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);
|
(section->poly).MakeEdgesInto(&edges);
|
||||||
|
|
||||||
// The trajectory along which the section will be swept
|
// The trajectory along which the section will be swept
|
||||||
SContour traj;
|
SContour traj;
|
||||||
ZERO(&traj);
|
ZERO(&traj);
|
||||||
|
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));
|
GetTrajectory(opA, &traj, &(section->poly));
|
||||||
|
}
|
||||||
|
|
||||||
if(traj.l.n <= 0) {
|
if(traj.l.n <= 0) {
|
||||||
edges.Clear();
|
edges.Clear();
|
||||||
|
@ -222,7 +243,17 @@ void Group::GenerateMeshForSweep(void) {
|
||||||
Vector origNormal = (traj.l.elem[1].p).Minus(origRef);
|
Vector origNormal = (traj.l.elem[1].p).Minus(origRef);
|
||||||
origNormal = origNormal.WithMagnitude(1);
|
origNormal = origNormal.WithMagnitude(1);
|
||||||
Vector oldRef = origRef, oldNormal = origNormal;
|
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
|
// The endcap at the start of the curve
|
||||||
SPolygon cap;
|
SPolygon cap;
|
||||||
|
@ -257,11 +288,18 @@ void Group::GenerateMeshForSweep(void) {
|
||||||
useNormal = (thisNormal.Plus(oldNormal)).ScaledBy(0.5);
|
useNormal = (thisNormal.Plus(oldNormal)).ScaledBy(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector useV, useU;
|
||||||
|
useNormal = 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
|
// Choose a new coordinate system, normal to the trajectory and
|
||||||
// with the minimum possible twist about the normal.
|
// with the minimum possible twist about the normal.
|
||||||
useNormal = useNormal.WithMagnitude(1);
|
useV = (useNormal.Cross(oldU)).WithMagnitude(1);
|
||||||
Vector useV = (useNormal.Cross(oldU)).WithMagnitude(1);
|
useU = (useV.Cross(useNormal)).WithMagnitude(1);
|
||||||
Vector useU = (useV.Cross(useNormal)).WithMagnitude(1);
|
}
|
||||||
|
|
||||||
Quaternion qi = Quaternion::From(oldU, oldV);
|
Quaternion qi = Quaternion::From(oldU, oldV);
|
||||||
Quaternion qf = Quaternion::From(useU, useV);
|
Quaternion qf = Quaternion::From(useU, useV);
|
||||||
|
@ -432,7 +470,14 @@ void Group::GenerateMesh(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(type == SWEEP) {
|
} 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) {
|
} else if(type == IMPORTED) {
|
||||||
// Triangles are just copied over, with the appropriate transformation
|
// Triangles are just copied over, with the appropriate transformation
|
||||||
// applied.
|
// applied.
|
||||||
|
|
25
sketch.h
25
sketch.h
|
@ -83,6 +83,7 @@ public:
|
||||||
static const int EXTRUDE = 5100;
|
static const int EXTRUDE = 5100;
|
||||||
static const int LATHE = 5101;
|
static const int LATHE = 5101;
|
||||||
static const int SWEEP = 5102;
|
static const int SWEEP = 5102;
|
||||||
|
static const int HELICAL_SWEEP = 5103;
|
||||||
static const int ROTATE = 5200;
|
static const int ROTATE = 5200;
|
||||||
static const int TRANSLATE = 5201;
|
static const int TRANSLATE = 5201;
|
||||||
static const int IMPORTED = 5300;
|
static const int IMPORTED = 5300;
|
||||||
|
@ -94,6 +95,8 @@ public:
|
||||||
bool clean;
|
bool clean;
|
||||||
hEntity activeWorkplane;
|
hEntity activeWorkplane;
|
||||||
double valA;
|
double valA;
|
||||||
|
double valB;
|
||||||
|
double valC;
|
||||||
DWORD color;
|
DWORD color;
|
||||||
|
|
||||||
static const int SOLVED_OKAY = 0;
|
static const int SOLVED_OKAY = 0;
|
||||||
|
@ -104,10 +107,15 @@ public:
|
||||||
SList<hConstraint> remove;
|
SList<hConstraint> remove;
|
||||||
} solved;
|
} solved;
|
||||||
|
|
||||||
|
// For drawings in 2d
|
||||||
static const int WORKPLANE_BY_POINT_ORTHO = 6000;
|
static const int WORKPLANE_BY_POINT_ORTHO = 6000;
|
||||||
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
|
static const int WORKPLANE_BY_LINE_SEGMENTS = 6001;
|
||||||
|
// For extrudes, translates, and rotates
|
||||||
static const int ONE_SIDED = 7000;
|
static const int ONE_SIDED = 7000;
|
||||||
static const int TWO_SIDED = 7001;
|
static const int TWO_SIDED = 7001;
|
||||||
|
// For helical sweeps
|
||||||
|
static const int RIGHT_HANDED = 8000;
|
||||||
|
static const int LEFT_HANDED = 8001;
|
||||||
int subtype;
|
int subtype;
|
||||||
|
|
||||||
bool skipFirst; // for step and repeat ops
|
bool skipFirst; // for step and repeat ops
|
||||||
|
@ -158,8 +166,8 @@ public:
|
||||||
void Activate(void);
|
void Activate(void);
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
|
|
||||||
static void AddParam(IdList<Param,hParam> *param, hParam hp, double v);
|
static void AddParam(ParamList *param, hParam hp, double v);
|
||||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
void Generate(EntityList *entity, ParamList *param);
|
||||||
// When a request generates entities from entities, and the source
|
// When a request generates entities from entities, and the source
|
||||||
// entities may have come from multiple requests, it's necessary to
|
// 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
|
// 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_PT_TO_LINE = 1003;
|
||||||
static const int REMAP_LINE_TO_FACE = 1004;
|
static const int REMAP_LINE_TO_FACE = 1004;
|
||||||
hEntity Remap(hEntity in, int copyNumber);
|
hEntity Remap(hEntity in, int copyNumber);
|
||||||
void MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in);
|
void MakeExtrusionLines(EntityList *el, hEntity in);
|
||||||
void MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt);
|
void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
|
||||||
void TagEdgesFromLineSegments(SEdgeList *sle);
|
void TagEdgesFromLineSegments(SEdgeList *sle);
|
||||||
void CopyEntity(IdList<Entity,hEntity> *el,
|
void CopyEntity(EntityList *el,
|
||||||
Entity *ep, int timesApplied, int remap,
|
Entity *ep, int timesApplied, int remap,
|
||||||
hParam dx, hParam dy, hParam dz,
|
hParam dx, hParam dy, hParam dz,
|
||||||
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
hParam qw, hParam qvx, hParam qvy, hParam qvz,
|
||||||
|
@ -190,7 +198,8 @@ public:
|
||||||
void AddQuadWithNormal(STriMeta meta, Vector out,
|
void AddQuadWithNormal(STriMeta meta, Vector out,
|
||||||
Vector a, Vector b, Vector c, Vector d);
|
Vector a, Vector b, Vector c, Vector d);
|
||||||
void GenerateMeshForStepAndRepeat(void);
|
void GenerateMeshForStepAndRepeat(void);
|
||||||
void GenerateMeshForSweep(void);
|
void GenerateMeshForSweep(bool helical,
|
||||||
|
Vector axisp, Vector axis, Vector onHelix);
|
||||||
void GenerateMesh(void);
|
void GenerateMesh(void);
|
||||||
void Draw(void);
|
void Draw(void);
|
||||||
|
|
||||||
|
@ -226,8 +235,8 @@ public:
|
||||||
|
|
||||||
bool construction;
|
bool construction;
|
||||||
|
|
||||||
static hParam AddParam(IdList<Param,hParam> *param, hParam hp);
|
static hParam AddParam(ParamList *param, hParam hp);
|
||||||
void Generate(IdList<Entity,hEntity> *entity, IdList<Param,hParam> *param);
|
void Generate(EntityList *entity, ParamList *param);
|
||||||
|
|
||||||
char *DescriptionString(void);
|
char *DescriptionString(void);
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,7 +101,10 @@ void vl(void); // debug function to validate
|
||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
class hEntity;
|
class hEntity;
|
||||||
|
class Param;
|
||||||
|
class hParam;
|
||||||
typedef IdList<Entity,hEntity> EntityList;
|
typedef IdList<Entity,hEntity> EntityList;
|
||||||
|
typedef IdList<Param,hParam> ParamList;
|
||||||
|
|
||||||
#include "sketch.h"
|
#include "sketch.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
@ -144,8 +147,8 @@ class System {
|
||||||
public:
|
public:
|
||||||
#define MAX_UNKNOWNS 200
|
#define MAX_UNKNOWNS 200
|
||||||
|
|
||||||
IdList<Entity,hEntity> entity;
|
EntityList entity;
|
||||||
IdList<Param,hParam> param;
|
ParamList param;
|
||||||
IdList<Equation,hEquation> eq;
|
IdList<Equation,hEquation> eq;
|
||||||
|
|
||||||
// In general, the tag indicates the subsys that a variable/equation
|
// In general, the tag indicates the subsys that a variable/equation
|
||||||
|
|
89
textwin.cpp
89
textwin.cpp
|
@ -626,6 +626,39 @@ void TextWindow::ScreenChangeMeshCombine(int link, DWORD v) {
|
||||||
SS.GenerateAll();
|
SS.GenerateAll();
|
||||||
SS.GW.ClearSuper();
|
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) {
|
void TextWindow::ScreenColor(int link, DWORD v) {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
|
@ -683,10 +716,6 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
g->h.v, &TextWindow::ScreenDeleteGroup);
|
g->h.v, &TextWindow::ScreenDeleteGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g->type == Group::IMPORTED) {
|
|
||||||
Printf(true, "%FtIMPORT%E '%s'", g->impFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE) {
|
if(g->type == Group::EXTRUDE) {
|
||||||
s = "EXTRUDE ";
|
s = "EXTRUDE ";
|
||||||
} else if(g->type == Group::TRANSLATE) {
|
} else if(g->type == Group::TRANSLATE) {
|
||||||
|
@ -709,10 +738,31 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
&TextWindow::ScreenChangeOneOrTwoSides,
|
&TextWindow::ScreenChangeOneOrTwoSides,
|
||||||
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
(!one ? "" : "two sides"), (!one ? "two sides" : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g->type == Group::LATHE) {
|
if(g->type == Group::LATHE) {
|
||||||
Printf(true, "%FtLATHE");
|
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) {
|
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
|
||||||
bool space;
|
bool space;
|
||||||
if(g->subtype == Group::ONE_SIDED) {
|
if(g->subtype == Group::ONE_SIDED) {
|
||||||
|
@ -734,9 +784,14 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
g->h.v, &TextWindow::ScreenChangeExprA);
|
g->h.v, &TextWindow::ScreenChangeExprA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(g->type == Group::IMPORTED) {
|
||||||
|
Printf(true, "%FtIMPORT%E '%s'", g->impFile);
|
||||||
|
}
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE ||
|
if(g->type == Group::EXTRUDE ||
|
||||||
g->type == Group::LATHE ||
|
g->type == Group::LATHE ||
|
||||||
g->type == Group::SWEEP ||
|
g->type == Group::SWEEP ||
|
||||||
|
g->type == Group::HELICAL_SWEEP ||
|
||||||
g->type == Group::IMPORTED)
|
g->type == Group::IMPORTED)
|
||||||
{
|
{
|
||||||
bool un = (g->meshCombine == Group::COMBINE_AS_UNION);
|
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 asy = (g->meshCombine == Group::COMBINE_AS_ASSEMBLE);
|
||||||
bool asa = (g->type == Group::IMPORTED);
|
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 "
|
"%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",
|
"%Fh%f%D%Ll%s%E%Fs%s%E",
|
||||||
&TextWindow::ScreenChangeMeshCombine,
|
&TextWindow::ScreenChangeMeshCombine,
|
||||||
|
@ -764,7 +819,8 @@ void TextWindow::ShowGroupInfo(void) {
|
||||||
|
|
||||||
if(g->type == Group::EXTRUDE ||
|
if(g->type == Group::EXTRUDE ||
|
||||||
g->type == Group::LATHE ||
|
g->type == Group::LATHE ||
|
||||||
g->type == Group::SWEEP)
|
g->type == Group::SWEEP ||
|
||||||
|
g->type == Group::HELICAL_SWEEP)
|
||||||
{
|
{
|
||||||
#define TWOX(v) v v
|
#define TWOX(v) v v
|
||||||
Printf(true, "%FtM_COLOR%E " TWOX(TWOX(TWOX("%Bp%D%f%Ln %Bd%E "))),
|
Printf(true, "%FtM_COLOR%E " TWOX(TWOX(TWOX("%Bp%D%f%Ln %Bd%E "))),
|
||||||
|
@ -997,6 +1053,27 @@ void TextWindow::EditControlDone(char *s) {
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
break;
|
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;
|
SS.later.showTW = true;
|
||||||
HideTextEditControl();
|
HideTextEditControl();
|
||||||
|
|
6
ui.h
6
ui.h
|
@ -64,6 +64,9 @@ public:
|
||||||
static const int EDIT_COLOR = 5;
|
static const int EDIT_COLOR = 5;
|
||||||
static const int EDIT_MESH_TOLERANCE = 6;
|
static const int EDIT_MESH_TOLERANCE = 6;
|
||||||
static const int EDIT_CAMERA_TANGENT = 7;
|
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 {
|
struct {
|
||||||
int meaning;
|
int meaning;
|
||||||
int i;
|
int i;
|
||||||
|
@ -103,6 +106,8 @@ public:
|
||||||
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
static void ScreenChangeOneOrTwoSides(int link, DWORD v);
|
||||||
static void ScreenChangeSkipFirst(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 ScreenChangeRightLeftHanded(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);
|
||||||
|
|
||||||
static void ScreenShowConfiguration(int link, DWORD v);
|
static void ScreenShowConfiguration(int link, DWORD v);
|
||||||
|
@ -164,6 +169,7 @@ public:
|
||||||
MNU_GROUP_EXTRUDE,
|
MNU_GROUP_EXTRUDE,
|
||||||
MNU_GROUP_LATHE,
|
MNU_GROUP_LATHE,
|
||||||
MNU_GROUP_SWEEP,
|
MNU_GROUP_SWEEP,
|
||||||
|
MNU_GROUP_HELICAL,
|
||||||
MNU_GROUP_ROT,
|
MNU_GROUP_ROT,
|
||||||
MNU_GROUP_TRANS,
|
MNU_GROUP_TRANS,
|
||||||
MNU_GROUP_IMPORT,
|
MNU_GROUP_IMPORT,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user