From 700b5d67197a300fec704a25bb3e449efcfe0a1d Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Wed, 22 Apr 2020 19:55:18 -0400 Subject: [PATCH] Allow Revolve and Helix end surface selection and constraints. (#584) --- src/group.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- src/sketch.h | 1 + src/srf/surface.cpp | 17 +++++++++++++---- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/group.cpp b/src/group.cpp index 733a06ce..3128ecc4 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -561,12 +561,18 @@ void Group::Generate(IdList *entity, AddParam(param, h.param(5), axis_dir.y); AddParam(param, h.param(6), axis_dir.z); + // Get some arbitrary point in the sketch, that will be used + // as a reference when defining end faces. + hEntity pt = { 0 }; + // 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)); if(e->group != opA) continue; + if(e->IsPoint()) pt = e->h; + e->CalculateNumerical(/*forExport=*/false); hEntity he = e->h; // one copy for each end of the revolved surface @@ -587,7 +593,7 @@ void Group::Generate(IdList *entity, // MakeLatheCircles(entity, param, he, axis_pos, axis_dir); MakeLatheSurfacesSelectable(entity, he, axis_dir); } - + MakeRevolveEndFaces(entity, pt); return; } @@ -607,12 +613,18 @@ void Group::Generate(IdList *entity, // distance to translate along the rotation axis AddParam(param, h.param(7), 20); + // Get some arbitrary point in the sketch, that will be used + // as a reference when defining end faces. + hEntity pt = { 0 }; + // 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)); if((e->group.v != opA.v) && !(e->h == predef.origin)) continue; + if(e->IsPoint()) pt = e->h; + e->CalculateNumerical(/*forExport=*/false); // one copy for each end of the helix @@ -644,6 +656,7 @@ void Group::Generate(IdList *entity, } } } + MakeRevolveEndFaces(entity, pt); return; } @@ -927,6 +940,32 @@ void Group::MakeLatheSurfacesSelectable(IdList *el, hEntity in, } } +void Group::MakeRevolveEndFaces(IdList *el, hEntity pt) +{ + if(pt.v == 0) return; + Group *src = SK.GetGroup(opA); + Vector n = src->polyLoops.normal; + + // When there is no loop normal (e.g. if the loop is broken), use normal of workplane + // as fallback, to avoid breaking constraints depending on the faces. + if(n.Equals(Vector::From(0.0, 0.0, 0.0)) && src->type == Group::Type::DRAWING_WORKPLANE) { + n = SK.GetEntity(src->h.entity(0))->Normal()->NormalN(); + } + + Entity en = {}; + en.type = Entity::Type::FACE_NORMAL_PT; + en.group = h; + + 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); + el->Add(&en); + + en.point[0] = Remap(pt, REMAP_LATHE_START); + en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START); + el->Add(&en); +} + void Group::MakeExtrusionTopBottomFaces(IdList *el, hEntity pt) { if(pt.v == 0) return; diff --git a/src/sketch.h b/src/sketch.h index 2465aefa..453df54d 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -285,6 +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 MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt); void CopyEntity(EntityList *el, Entity *ep, int timesApplied, int remap, diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index a61713c3..fa3605ff 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -674,14 +674,23 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector // So we can now generate the end caps of the extrusion within // a translated and rotated (and maybe mirrored) version of that csys. SSurface s0, s1; - s0 = SSurface::FromPlane(orig.RotatedAbout(pt, axis, angles).Plus(axis.ScaledBy(dists)), + s0 = SSurface::FromPlane(orig.RotatedAbout(pt, axis, angles).Plus(axis.ScaledBy(dists)), u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles)); s0.color = color; - s1 = SSurface::FromPlane( + + hEntity face0 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_END); + s0.face = face0.v; + + s1 = SSurface::FromPlane( orig.Plus(u).RotatedAbout(pt, axis, anglef).Plus(axis.ScaledBy(distf)), u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef)); - s1.color = color; - hSSurface hs0 = surface.AddAndAssignId(&s0), hs1 = surface.AddAndAssignId(&s1); + s1.color = color; + + hEntity face1 = group->Remap(Entity::NO_ENTITY, Group::REMAP_LATHE_START); + s1.face = face1.v; + + hSSurface hs0 = surface.AddAndAssignId(&s0); + hSSurface hs1 = surface.AddAndAssignId(&s1); // Now we actually build and trim the swept surfaces. One loop at a time. for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {