Generate primitives for lathe groups.
The primitives that are generated are circles from points and faces from axis-perpendicular line segments.
This commit is contained in:
parent
9c4d1cb9b0
commit
6dced8052b
|
@ -366,6 +366,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) {
|
||||||
Vector a = SK.GetEntity(point[0])->PointGetNum();
|
Vector a = SK.GetEntity(point[0])->PointGetNum();
|
||||||
Vector b = SK.GetEntity(point[1])->PointGetNum();
|
Vector b = SK.GetEntity(point[1])->PointGetNum();
|
||||||
sb = SBezier::From(a, b);
|
sb = SBezier::From(a, b);
|
||||||
|
sb.entity = h.v;
|
||||||
sbl->l.Add(&sb);
|
sbl->l.Add(&sb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
111
src/group.cpp
111
src/group.cpp
|
@ -283,7 +283,7 @@ std::string Group::DescriptionString(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::Activate(void) {
|
void Group::Activate(void) {
|
||||||
if(type == EXTRUDE || type == IMPORTED) {
|
if(type == EXTRUDE || type == IMPORTED || type == LATHE || type == TRANSLATE || type == ROTATE) {
|
||||||
SS.GW.showFaces = true;
|
SS.GW.showFaces = true;
|
||||||
} else {
|
} else {
|
||||||
SS.GW.showFaces = false;
|
SS.GW.showFaces = false;
|
||||||
|
@ -390,6 +390,43 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
}
|
}
|
||||||
|
|
||||||
case LATHE: {
|
case LATHE: {
|
||||||
|
Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum();
|
||||||
|
Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum();
|
||||||
|
|
||||||
|
AddParam(param, h.param(0), axis_dir.x);
|
||||||
|
AddParam(param, h.param(1), axis_dir.y);
|
||||||
|
AddParam(param, h.param(2), axis_dir.z);
|
||||||
|
|
||||||
|
// Remapped entity index.
|
||||||
|
int ai = 1;
|
||||||
|
|
||||||
|
for(i = 0; i < entity->n; i++) {
|
||||||
|
Entity *e = &(entity->elem[i]);
|
||||||
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
|
e->CalculateNumerical(false);
|
||||||
|
hEntity he = e->h;
|
||||||
|
|
||||||
|
// As soon as I call CopyEntity, e may become invalid! That
|
||||||
|
// adds entities, which may cause a realloc.
|
||||||
|
CopyEntity(entity, SK.GetEntity(predef.origin), 0, ai,
|
||||||
|
h.param(0), h.param(1), h.param(2),
|
||||||
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
|
true, false);
|
||||||
|
|
||||||
|
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_START,
|
||||||
|
h.param(0), h.param(1), h.param(2),
|
||||||
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
|
true, false);
|
||||||
|
|
||||||
|
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_END,
|
||||||
|
h.param(0), h.param(1), h.param(2),
|
||||||
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
|
true, false);
|
||||||
|
|
||||||
|
MakeLatheCircles(entity, param, he, axis_pos, axis_dir, ai);
|
||||||
|
ai++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,6 +637,78 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *param, hEntity in, Vector pt, Vector axis, int ai) {
|
||||||
|
Entity *ep = SK.GetEntity(in);
|
||||||
|
|
||||||
|
Entity en = {};
|
||||||
|
if(ep->IsPoint()) {
|
||||||
|
// A point gets revolved to form an arc.
|
||||||
|
en.point[0] = Remap(predef.origin, ai);
|
||||||
|
en.point[1] = Remap(ep->h, REMAP_LATHE_START);
|
||||||
|
en.point[2] = Remap(ep->h, REMAP_LATHE_END);
|
||||||
|
|
||||||
|
// Get arc center and point on arc.
|
||||||
|
Entity *pc = SK.GetEntity(en.point[0]);
|
||||||
|
Entity *pp = SK.GetEntity(en.point[1]);
|
||||||
|
|
||||||
|
// Project arc point to the revolution axis and use it for arc center.
|
||||||
|
double k = pp->numPoint.Minus(pt).Dot(axis) / axis.Dot(axis);
|
||||||
|
pc->numPoint = pt.Plus(axis.ScaledBy(k));
|
||||||
|
|
||||||
|
// Create arc entity.
|
||||||
|
en.group = h;
|
||||||
|
en.construction = ep->construction;
|
||||||
|
en.style = ep->style;
|
||||||
|
en.h = Remap(ep->h, REMAP_PT_TO_ARC);
|
||||||
|
en.type = Entity::ARC_OF_CIRCLE;
|
||||||
|
|
||||||
|
// Generate a normal.
|
||||||
|
Entity n = {};
|
||||||
|
n.workplane = en.workplane;
|
||||||
|
n.h = Remap(ep->h, REMAP_PT_TO_NORMAL);
|
||||||
|
n.group = en.group;
|
||||||
|
n.style = en.style;
|
||||||
|
n.type = Entity::NORMAL_N_COPY;
|
||||||
|
|
||||||
|
// Create basis for the normal.
|
||||||
|
Vector nu = pp->numPoint.Minus(pc->numPoint).WithMagnitude(1.0);
|
||||||
|
Vector nv = nu.Cross(axis).WithMagnitude(1.0);
|
||||||
|
n.numNormal = Quaternion::From(nv, nu);
|
||||||
|
|
||||||
|
// The point determines where the normal gets displayed on-screen;
|
||||||
|
// it's entirely cosmetic.
|
||||||
|
n.point[0] = en.point[0];
|
||||||
|
el->Add(&n);
|
||||||
|
en.normal = n.h;
|
||||||
|
el->Add(&en);
|
||||||
|
} else if(ep->type == Entity::LINE_SEGMENT) {
|
||||||
|
// An axis-perpendicular line gets revolved to form a face.
|
||||||
|
Vector a = SK.GetEntity(ep->point[0])->PointGetNum();
|
||||||
|
Vector b = SK.GetEntity(ep->point[1])->PointGetNum();
|
||||||
|
Vector u = b.Minus(a).WithMagnitude(1.0);
|
||||||
|
|
||||||
|
// Check for perpendicularity: calculate cosine of the angle
|
||||||
|
// between axis and line direction and check that
|
||||||
|
// cos(angle) == 0 <-> angle == +-90 deg.
|
||||||
|
if(fabs(u.Dot(axis) / axis.Magnitude()) < ANGLE_COS_EPS) {
|
||||||
|
en.param[0] = h.param(0);
|
||||||
|
en.param[1] = h.param(1);
|
||||||
|
en.param[2] = h.param(2);
|
||||||
|
Vector v = axis.Cross(u).WithMagnitude(1.0);
|
||||||
|
Vector n = u.Cross(v);
|
||||||
|
en.numNormal = Quaternion::From(0, n.x, n.y, n.z);
|
||||||
|
|
||||||
|
en.group = h;
|
||||||
|
en.construction = ep->construction;
|
||||||
|
en.style = ep->style;
|
||||||
|
en.h = Remap(ep->h, REMAP_LINE_TO_FACE);
|
||||||
|
en.type = Entity::FACE_NORMAL_PT;
|
||||||
|
en.point[0] = ep->point[0];
|
||||||
|
el->Add(&en);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
|
void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
|
||||||
{
|
{
|
||||||
if(pt.v == 0) return;
|
if(pt.v == 0) return;
|
||||||
|
|
|
@ -283,7 +283,7 @@ void Group::GenerateShellAndMesh(void) {
|
||||||
SBezierLoopSetSet *sblss = &(src->bezierLoops);
|
SBezierLoopSetSet *sblss = &(src->bezierLoops);
|
||||||
SBezierLoopSet *sbls;
|
SBezierLoopSet *sbls;
|
||||||
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
|
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
|
||||||
thisShell.MakeFromRevolutionOf(sbls, pt, axis, color);
|
thisShell.MakeFromRevolutionOf(sbls, pt, axis, color, this);
|
||||||
}
|
}
|
||||||
} else if(type == IMPORTED) {
|
} else if(type == IMPORTED) {
|
||||||
// The imported shell or mesh are copied over, with the appropriate
|
// The imported shell or mesh are copied over, with the appropriate
|
||||||
|
|
|
@ -214,10 +214,15 @@ public:
|
||||||
REMAP_TOP = 1001,
|
REMAP_TOP = 1001,
|
||||||
REMAP_BOTTOM = 1002,
|
REMAP_BOTTOM = 1002,
|
||||||
REMAP_PT_TO_LINE = 1003,
|
REMAP_PT_TO_LINE = 1003,
|
||||||
REMAP_LINE_TO_FACE = 1004
|
REMAP_LINE_TO_FACE = 1004,
|
||||||
|
REMAP_LATHE_START = 1006,
|
||||||
|
REMAP_LATHE_END = 1007,
|
||||||
|
REMAP_PT_TO_ARC = 1008,
|
||||||
|
REMAP_PT_TO_NORMAL = 1009,
|
||||||
};
|
};
|
||||||
hEntity Remap(hEntity in, int copyNumber);
|
hEntity Remap(hEntity in, int copyNumber);
|
||||||
void MakeExtrusionLines(EntityList *el, hEntity in);
|
void MakeExtrusionLines(EntityList *el, hEntity in);
|
||||||
|
void MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *param, hEntity in, Vector pt, Vector axis, int ai);
|
||||||
void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
|
void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt);
|
||||||
void CopyEntity(EntityList *el,
|
void CopyEntity(EntityList *el,
|
||||||
Entity *ep, int timesApplied, int remap,
|
Entity *ep, int timesApplied, int remap,
|
||||||
|
|
|
@ -94,6 +94,7 @@ inline double ffabs(double v) { return (v > 0) ? v : (-v); }
|
||||||
|
|
||||||
#define CO(v) (v).x, (v).y, (v).z
|
#define CO(v) (v).x, (v).y, (v).z
|
||||||
|
|
||||||
|
#define ANGLE_COS_EPS (1e-6)
|
||||||
#define LENGTH_EPS (1e-6)
|
#define LENGTH_EPS (1e-6)
|
||||||
#define VERY_POSITIVE (1e10)
|
#define VERY_POSITIVE (1e10)
|
||||||
#define VERY_NEGATIVE (-1e10)
|
#define VERY_NEGATIVE (-1e10)
|
||||||
|
|
|
@ -600,7 +600,7 @@ typedef struct {
|
||||||
hSSurface d[4];
|
hSSurface d[4];
|
||||||
} Revolved;
|
} Revolved;
|
||||||
|
|
||||||
void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color)
|
void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color, Group *group)
|
||||||
{
|
{
|
||||||
SBezierLoop *sbl;
|
SBezierLoop *sbl;
|
||||||
|
|
||||||
|
@ -654,6 +654,14 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
||||||
(PI/2)*j,
|
(PI/2)*j,
|
||||||
(PI/2)*(j+1));
|
(PI/2)*(j+1));
|
||||||
ss.color = color;
|
ss.color = color;
|
||||||
|
if(sb->entity != 0) {
|
||||||
|
hEntity he;
|
||||||
|
he.v = sb->entity;
|
||||||
|
hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE);
|
||||||
|
if(SK.entity.FindByIdNoOops(hface) != NULL) {
|
||||||
|
ss.face = hface.v;
|
||||||
|
}
|
||||||
|
}
|
||||||
revs.d[j] = surface.AddAndAssignId(&ss);
|
revs.d[j] = surface.AddAndAssignId(&ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
int deg;
|
int deg;
|
||||||
Vector ctrl[4];
|
Vector ctrl[4];
|
||||||
double weight[4];
|
double weight[4];
|
||||||
|
uint32_t entity;
|
||||||
|
|
||||||
Vector PointAt(double t);
|
Vector PointAt(double t);
|
||||||
Vector TangentAt(double t);
|
Vector TangentAt(double t);
|
||||||
|
@ -363,7 +364,7 @@ public:
|
||||||
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||||
RgbaColor color);
|
RgbaColor color);
|
||||||
void MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
void MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
||||||
RgbaColor color);
|
RgbaColor color, Group *group);
|
||||||
|
|
||||||
void MakeFromUnionOf(SShell *a, SShell *b);
|
void MakeFromUnionOf(SShell *a, SShell *b);
|
||||||
void MakeFromDifferenceOf(SShell *a, SShell *b);
|
void MakeFromDifferenceOf(SShell *a, SShell *b);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user