Add rotated face from point entity type. Fixes issue 585, problems constraining to Revolve and Helix ends. (#586)

pull/589/head
phkahler 2020-04-24 17:37:55 -04:00 committed by GitHub
parent 700b5d6719
commit f36ac500a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 34 deletions

View File

@ -120,6 +120,7 @@ void Entity::GetReferencePoints(std::vector<Vector> *refs) {
case Type::FACE_N_ROT_TRANS: case Type::FACE_N_ROT_TRANS:
case Type::FACE_N_TRANS: case Type::FACE_N_TRANS:
case Type::FACE_N_ROT_AA: case Type::FACE_N_ROT_AA:
case Type::FACE_ROT_NORMAL_PT:
break; break;
} }
} }
@ -755,6 +756,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) {
case Type::FACE_N_ROT_TRANS: case Type::FACE_N_ROT_TRANS:
case Type::FACE_N_TRANS: case Type::FACE_N_TRANS:
case Type::FACE_N_ROT_AA: case Type::FACE_N_ROT_AA:
case Type::FACE_ROT_NORMAL_PT:
// Do nothing; these are drawn with the triangle mesh // Do nothing; these are drawn with the triangle mesh
return; return;
} }

View File

@ -701,6 +701,7 @@ bool EntityBase::IsFace() const {
case Type::FACE_N_ROT_TRANS: case Type::FACE_N_ROT_TRANS:
case Type::FACE_N_TRANS: case Type::FACE_N_TRANS:
case Type::FACE_N_ROT_AA: case Type::FACE_N_ROT_AA:
case Type::FACE_ROT_NORMAL_PT:
return true; return true;
default: default:
return false; return false;
@ -728,7 +729,7 @@ ExprVector EntityBase::FaceGetNormalExprs() const {
r = q.Rotate(r); r = q.Rotate(r);
} else if(type == Type::FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
} else if(type == Type::FACE_N_ROT_AA) { } else if((type == Type::FACE_N_ROT_AA) || (type == Type::FACE_ROT_NORMAL_PT)) {
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
ExprQuaternion q = GetAxisAngleQuaternionExprs(3); ExprQuaternion q = GetAxisAngleQuaternionExprs(3);
r = q.Rotate(r); r = q.Rotate(r);
@ -751,7 +752,7 @@ Vector EntityBase::FaceGetNormalNum() const {
r = q.Rotate(r); r = q.Rotate(r);
} else if(type == Type::FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
} else if(type == Type::FACE_N_ROT_AA) { } else if((type == Type::FACE_N_ROT_AA) || (type == Type::FACE_ROT_NORMAL_PT)) {
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
Quaternion q = GetAxisAngleQuaternion(3); Quaternion q = GetAxisAngleQuaternion(3);
r = q.Rotate(r); r = q.Rotate(r);
@ -761,7 +762,7 @@ Vector EntityBase::FaceGetNormalNum() const {
ExprVector EntityBase::FaceGetPointExprs() const { ExprVector EntityBase::FaceGetPointExprs() const {
ExprVector r; ExprVector r;
if(type == Type::FACE_NORMAL_PT) { if((type == Type::FACE_NORMAL_PT) || (type==Type::FACE_ROT_NORMAL_PT)) {
r = SK.GetEntity(point[0])->PointGetExprs(); r = SK.GetEntity(point[0])->PointGetExprs();
} else if(type == Type::FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
@ -790,7 +791,7 @@ ExprVector EntityBase::FaceGetPointExprs() const {
Vector EntityBase::FaceGetPointNum() const { Vector EntityBase::FaceGetPointNum() const {
Vector r; Vector r;
if(type == Type::FACE_NORMAL_PT) { if((type == Type::FACE_NORMAL_PT) || (type==Type::FACE_ROT_NORMAL_PT)) {
r = SK.GetEntity(point[0])->PointGetNum(); r = SK.GetEntity(point[0])->PointGetNum();
} else if(type == Type::FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
r = numPoint; r = numPoint;

View File

@ -565,6 +565,12 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
// as a reference when defining end faces. // as a reference when defining end faces.
hEntity pt = { 0 }; hEntity pt = { 0 };
int ai = 0, af = 2;
if (subtype == Subtype::TWO_SIDED)
{
ai = -1;
af = 1;
}
// Not using range-for here because we're changing the size of entity in the loop. // Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) { for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->Get(i)); Entity *e = &(entity->Get(i));
@ -576,24 +582,20 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(/*forExport=*/false); e->CalculateNumerical(/*forExport=*/false);
hEntity he = e->h; hEntity he = e->h;
// one copy for each end of the revolved surface // one copy for each end of the revolved surface
for(a = 0; a < 2; a++) { CopyEntity(entity, e, ai, REMAP_LATHE_START, h.param(0),
//! @todo is this check redundant? h.param(1), h.param(2), h.param(3), h.param(4), h.param(5),
Entity *e = &(entity->Get(i)); h.param(6), NO_PARAM, CopyAs::N_ROT_AA);
if(e->group != opA)
continue; CopyEntity(entity, e, af, REMAP_LATHE_END, h.param(0),
h.param(1), h.param(2), h.param(3), h.param(4), h.param(5),
h.param(6), NO_PARAM, CopyAs::N_ROT_AA);
e->CalculateNumerical(false);
CopyEntity(entity, e, a * 2 - (subtype == Subtype::ONE_SIDED ? 0 : 1),
(a == 1) ? REMAP_LATHE_END : REMAP_LATHE_START, h.param(0),
h.param(1), h.param(2), h.param(3), h.param(4), h.param(5),
h.param(6), NO_PARAM, CopyAs::N_ROT_AA);
}
// Arcs are not generated for revolve groups, for now, because our current arc // Arcs are not generated for revolve groups, for now, because our current arc
// entity is not chiral, and dragging a revolve may break the arc by inverting it. // entity is not chiral, and dragging a revolve may break the arc by inverting it.
// MakeLatheCircles(entity, param, he, axis_pos, axis_dir); // MakeLatheCircles(entity, param, he, axis_pos, axis_dir);
MakeLatheSurfacesSelectable(entity, he, axis_dir); MakeLatheSurfacesSelectable(entity, he, axis_dir);
} }
MakeRevolveEndFaces(entity, pt); MakeRevolveEndFaces(entity, pt, ai, af);
return; return;
} }
@ -617,6 +619,13 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
// as a reference when defining end faces. // as a reference when defining end faces.
hEntity pt = { 0 }; hEntity pt = { 0 };
int ai = 0, af = 2; // initial and final number of transformations
if (subtype != Subtype::ONE_SIDED)
{
ai = -1;
af = 1;
}
// Not using range-for here because we're changing the size of entity in the loop. // Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) { for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->Get(i)); Entity *e = &(entity->Get(i));
@ -628,14 +637,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(/*forExport=*/false); e->CalculateNumerical(/*forExport=*/false);
// one copy for each end of the helix // one copy for each end of the helix
for(a = 0; a < 2; a++) { CopyEntity(entity, e, ai, REMAP_LATHE_START, h.param(0),
Entity *e = &(entity->Get(i)); h.param(1), h.param(2), h.param(3), h.param(4), h.param(5),
e->CalculateNumerical(false); h.param(6), h.param(7), CopyAs::N_ROT_AXIS_TRANS);
CopyEntity(entity, e, a * 2 - (subtype == Subtype::ONE_SIDED ? 0 : 1),
(a == 1) ? REMAP_LATHE_END : REMAP_LATHE_START, h.param(0), CopyEntity(entity, e, af, REMAP_LATHE_END, h.param(0),
h.param(1), h.param(2), h.param(3), h.param(4), h.param(5), h.param(1), h.param(2), h.param(3), h.param(4), h.param(5),
h.param(6), h.param(7), CopyAs::N_ROT_AXIS_TRANS); h.param(6), h.param(7), CopyAs::N_ROT_AXIS_TRANS);
}
// For point entities on the axis, create a construction line // For point entities on the axis, create a construction line
e = &(entity->Get(i)); e = &(entity->Get(i));
if(e->IsPoint()) { if(e->IsPoint()) {
@ -656,7 +665,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
} }
} }
} }
MakeRevolveEndFaces(entity, pt); MakeRevolveEndFaces(entity, pt, ai, af);
return; return;
} }
@ -940,7 +949,10 @@ void Group::MakeLatheSurfacesSelectable(IdList<Entity, hEntity> *el, hEntity in,
} }
} }
void Group::MakeRevolveEndFaces(IdList<Entity,hEntity> *el, hEntity pt) // For Revolve and Helix groups the end faces are remapped from an arbitrary
// point on the sketch. We reference the transformed point but there is
// no existing normal so we need to define the rotation and timesApplied.
void Group::MakeRevolveEndFaces(IdList<Entity,hEntity> *el, hEntity pt, int ai, int af)
{ {
if(pt.v == 0) return; if(pt.v == 0) return;
Group *src = SK.GetGroup(opA); Group *src = SK.GetGroup(opA);
@ -953,16 +965,27 @@ void Group::MakeRevolveEndFaces(IdList<Entity,hEntity> *el, hEntity pt)
} }
Entity en = {}; Entity en = {};
en.type = Entity::Type::FACE_NORMAL_PT; en.type = Entity::Type::FACE_ROT_NORMAL_PT;
en.group = h; en.group = h;
// The center of rotation
en.param[0] = h.param(0);
en.param[1] = h.param(1);
en.param[2] = h.param(2);
// The rotation quaternion
en.param[3] = h.param(3);
en.param[4] = h.param(4);
en.param[5] = h.param(5);
en.param[6] = h.param(6);
en.numNormal = Quaternion::From(0, n.x, n.y, n.z); en.numNormal = Quaternion::From(0, n.x, n.y, n.z);
en.point[0] = Remap(pt, REMAP_LATHE_END); en.point[0] = Remap(pt, REMAP_LATHE_START);
en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_END); en.timesApplied = ai;
en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START);
el->Add(&en); el->Add(&en);
en.point[0] = Remap(pt, REMAP_LATHE_START); en.point[0] = Remap(pt, REMAP_LATHE_END);
en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START); en.timesApplied = af;
en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_END);
el->Add(&en); el->Add(&en);
} }
@ -1086,6 +1109,7 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
case Entity::Type::FACE_N_ROT_TRANS: case Entity::Type::FACE_N_ROT_TRANS:
case Entity::Type::FACE_N_TRANS: case Entity::Type::FACE_N_TRANS:
case Entity::Type::FACE_N_ROT_AA: case Entity::Type::FACE_N_ROT_AA:
case Entity::Type::FACE_ROT_NORMAL_PT:
if(as == CopyAs::N_TRANS) { if(as == CopyAs::N_TRANS) {
en.type = Entity::Type::FACE_N_TRANS; en.type = Entity::Type::FACE_N_TRANS;
en.param[0] = dx; en.param[0] = dx;

View File

@ -285,7 +285,7 @@ public:
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); void MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *param, hEntity in, Vector pt, Vector axis);
void MakeLatheSurfacesSelectable(IdList<Entity, hEntity> *el, hEntity in, Vector axis); void MakeLatheSurfacesSelectable(IdList<Entity, hEntity> *el, hEntity in, Vector axis);
void MakeRevolveEndFaces(IdList<Entity,hEntity> *el, hEntity pt); void MakeRevolveEndFaces(IdList<Entity,hEntity> *el, hEntity pt, int ai, int af);
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,
@ -407,6 +407,7 @@ public:
FACE_N_ROT_TRANS = 5002, FACE_N_ROT_TRANS = 5002,
FACE_N_TRANS = 5003, FACE_N_TRANS = 5003,
FACE_N_ROT_AA = 5004, FACE_N_ROT_AA = 5004,
FACE_ROT_NORMAL_PT = 5005,
WORKPLANE = 10000, WORKPLANE = 10000,
LINE_SEGMENT = 11000, LINE_SEGMENT = 11000,

View File

@ -678,7 +678,7 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector
u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles)); u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles));
s0.color = color; s0.color = color;
hEntity face0 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_END); hEntity face0 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_START);
s0.face = face0.v; s0.face = face0.v;
s1 = SSurface::FromPlane( s1 = SSurface::FromPlane(
@ -686,7 +686,7 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector
u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef)); u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef));
s1.color = color; s1.color = color;
hEntity face1 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_START); hEntity face1 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_END);
s1.face = face1.v; s1.face = face1.v;
hSSurface hs0 = surface.AddAndAssignId(&s0); hSSurface hs0 = surface.AddAndAssignId(&s0);