diff --git a/src/drawentity.cpp b/src/drawentity.cpp index de93d73..54477c8 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -120,6 +120,7 @@ void Entity::GetReferencePoints(std::vector *refs) { case Type::FACE_N_ROT_TRANS: case Type::FACE_N_TRANS: case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: break; } } @@ -755,6 +756,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) { case Type::FACE_N_ROT_TRANS: case Type::FACE_N_TRANS: case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: // Do nothing; these are drawn with the triangle mesh return; } diff --git a/src/entity.cpp b/src/entity.cpp index 38800ab..344e1ac 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -701,6 +701,7 @@ bool EntityBase::IsFace() const { case Type::FACE_N_ROT_TRANS: case Type::FACE_N_TRANS: case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: return true; default: return false; @@ -728,7 +729,7 @@ ExprVector EntityBase::FaceGetNormalExprs() const { r = q.Rotate(r); } else if(type == Type::FACE_N_TRANS) { 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); ExprQuaternion q = GetAxisAngleQuaternionExprs(3); r = q.Rotate(r); @@ -751,7 +752,7 @@ Vector EntityBase::FaceGetNormalNum() const { r = q.Rotate(r); } else if(type == Type::FACE_N_TRANS) { 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); Quaternion q = GetAxisAngleQuaternion(3); r = q.Rotate(r); @@ -761,7 +762,7 @@ Vector EntityBase::FaceGetNormalNum() const { ExprVector EntityBase::FaceGetPointExprs() const { 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(); } else if(type == Type::FACE_XPROD) { r = ExprVector::From(numPoint); @@ -790,7 +791,7 @@ ExprVector EntityBase::FaceGetPointExprs() const { Vector EntityBase::FaceGetPointNum() const { 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(); } else if(type == Type::FACE_XPROD) { r = numPoint; diff --git a/src/group.cpp b/src/group.cpp index 3128ecc..686f4ce 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -565,6 +565,12 @@ void Group::Generate(IdList *entity, // as a reference when defining end faces. 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. for(i = 0; i < entity->n; i++) { Entity *e = &(entity->Get(i)); @@ -576,24 +582,20 @@ void Group::Generate(IdList *entity, e->CalculateNumerical(/*forExport=*/false); hEntity he = e->h; // one copy for each end of the revolved surface - for(a = 0; a < 2; a++) { - //! @todo is this check redundant? - Entity *e = &(entity->Get(i)); - if(e->group != opA) - continue; + CopyEntity(entity, e, ai, 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); + + 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 // entity is not chiral, and dragging a revolve may break the arc by inverting it. // MakeLatheCircles(entity, param, he, axis_pos, axis_dir); MakeLatheSurfacesSelectable(entity, he, axis_dir); } - MakeRevolveEndFaces(entity, pt); + MakeRevolveEndFaces(entity, pt, ai, af); return; } @@ -617,6 +619,13 @@ void Group::Generate(IdList *entity, // as a reference when defining end faces. 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. for(i = 0; i < entity->n; i++) { Entity *e = &(entity->Get(i)); @@ -628,14 +637,14 @@ void Group::Generate(IdList *entity, e->CalculateNumerical(/*forExport=*/false); // one copy for each end of the helix - for(a = 0; a < 2; a++) { - Entity *e = &(entity->Get(i)); - 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), h.param(7), CopyAs::N_ROT_AXIS_TRANS); - } + CopyEntity(entity, e, ai, REMAP_LATHE_START, h.param(0), + 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); + + 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), h.param(7), CopyAs::N_ROT_AXIS_TRANS); + // For point entities on the axis, create a construction line e = &(entity->Get(i)); if(e->IsPoint()) { @@ -656,7 +665,7 @@ void Group::Generate(IdList *entity, } } } - MakeRevolveEndFaces(entity, pt); + MakeRevolveEndFaces(entity, pt, ai, af); return; } @@ -940,7 +949,10 @@ void Group::MakeLatheSurfacesSelectable(IdList *el, hEntity in, } } -void Group::MakeRevolveEndFaces(IdList *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 *el, hEntity pt, int ai, int af) { if(pt.v == 0) return; Group *src = SK.GetGroup(opA); @@ -953,16 +965,27 @@ void Group::MakeRevolveEndFaces(IdList *el, hEntity pt) } Entity en = {}; - en.type = Entity::Type::FACE_NORMAL_PT; + en.type = Entity::Type::FACE_ROT_NORMAL_PT; 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.point[0] = Remap(pt, REMAP_LATHE_END); - en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_END); + en.point[0] = Remap(pt, REMAP_LATHE_START); + en.timesApplied = ai; + en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START); el->Add(&en); - en.point[0] = Remap(pt, REMAP_LATHE_START); - en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START); + en.point[0] = Remap(pt, REMAP_LATHE_END); + en.timesApplied = af; + en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_END); el->Add(&en); } @@ -1086,6 +1109,7 @@ void Group::CopyEntity(IdList *el, case Entity::Type::FACE_N_ROT_TRANS: case Entity::Type::FACE_N_TRANS: case Entity::Type::FACE_N_ROT_AA: + case Entity::Type::FACE_ROT_NORMAL_PT: if(as == CopyAs::N_TRANS) { en.type = Entity::Type::FACE_N_TRANS; en.param[0] = dx; diff --git a/src/sketch.h b/src/sketch.h index 453df54..a4ef89a 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -285,7 +285,7 @@ public: void MakeExtrusionLines(EntityList *el, hEntity in); void MakeLatheCircles(IdList *el, IdList *param, hEntity in, Vector pt, Vector axis); void MakeLatheSurfacesSelectable(IdList *el, hEntity in, Vector axis); - void MakeRevolveEndFaces(IdList *el, hEntity pt); + void MakeRevolveEndFaces(IdList *el, hEntity pt, int ai, int af); void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt); void CopyEntity(EntityList *el, Entity *ep, int timesApplied, int remap, @@ -407,6 +407,7 @@ public: FACE_N_ROT_TRANS = 5002, FACE_N_TRANS = 5003, FACE_N_ROT_AA = 5004, + FACE_ROT_NORMAL_PT = 5005, WORKPLANE = 10000, LINE_SEGMENT = 11000, diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index fa3605f..01d5e9e 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -678,7 +678,7 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles)); 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; 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)); 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; hSSurface hs0 = surface.AddAndAssignId(&s0);