Skip to content

Commit

Permalink
Let tangent arc modify the original entities.
Browse files Browse the repository at this point in the history
Modifying the original entities instead of deleting them, retains the
original associated constraints. This makes creating rounded rectangles
a lot easier.
  • Loading branch information
bcmpinc committed Jul 22, 2018
1 parent 8426992 commit f7a09e0
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 49 deletions.
108 changes: 66 additions & 42 deletions src/modify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,46 +161,65 @@ Vector GraphicsWindow::ParametricCurve::TangentAt(double t) {
return t;
}
}
hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
bool extraConstraints, hEntity orig, hEntity arc, bool arcFinish)
/** Changes or copies the given entity and connects it to the arc.
* \param t Where on this parametric curve does it connect to the arc.
* \param reuseOrig Should the original entity be modified
* \param orig The original entity.
* \param arc The arc that will be connected to.
* \param arcFinish Whether to connect to the end point of the arc.
* \param pointf When changing the original entity, whether the end point should be modified.
*/
void GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
bool reuseOrig, hEntity orig, hEntity arc, bool arcFinish, bool pointf)
{
hRequest hr;
Entity *e;
if(isLine) {
hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false),
e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]);
if(extraConstraints) {
if (reuseOrig) {
e = SK.GetEntity(orig);
int i = pointf ? 1 : 0;
SK.GetEntity(e->point[i])->PointForceTo(PointAt(t));
ConstrainPointIfCoincident(e->point[i]);
} else {
hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false),
e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]);
Constraint::Constrain(Constraint::Type::PT_ON_LINE,
hr.entity(1), Entity::NO_ENTITY, orig);
}
Constraint::Constrain(Constraint::Type::ARC_LINE_TANGENT,
Entity::NO_ENTITY, Entity::NO_ENTITY,
arc, e->h, /*other=*/arcFinish, /*other2=*/false);
} else {
hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false),
e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(p0);
if(dtheta > 0) {
SK.GetEntity(e->point[1])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[2])->PointForceTo(PointAt(1));
if (reuseOrig) {
e = SK.GetEntity(orig);
int i = pointf ? 2 : 1;
SK.GetEntity(e->point[i])->PointForceTo(PointAt(t));
ConstrainPointIfCoincident(e->point[i]);
} else {
SK.GetEntity(e->point[2])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false),
e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(p0);
if(dtheta > 0) {
SK.GetEntity(e->point[1])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[2])->PointForceTo(PointAt(1));
} else {
SK.GetEntity(e->point[2])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
}
ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]);
ConstrainPointIfCoincident(e->point[2]);
}
ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]);
ConstrainPointIfCoincident(e->point[2]);
// The tangency constraint alone is enough to fully constrain it,
// so there's no need for more.
Constraint::Constrain(Constraint::Type::CURVE_CURVE_TANGENT,
Entity::NO_ENTITY, Entity::NO_ENTITY,
arc, e->h, /*other=*/arcFinish, /*other2=*/(dtheta < 0));
}
return hr;
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -388,6 +407,27 @@ void GraphicsWindow::MakeTangentArc() {

SS.UndoRemember();

if (SS.tangentArcModify) {
// Delete the coincident constraint for the removed point.
SK.constraint.ClearTags();
for(i = 0; i < SK.constraint.n; i++) {
Constraint *cs = &(SK.constraint.elem[i]);
if(cs->group.v != activeGroup.v) continue;
if(cs->workplane.v != ActiveWorkplane().v) continue;
if(cs->type != Constraint::Type::POINTS_COINCIDENT) continue;
if (SK.GetEntity(cs->ptA)->PointGetNum().Equals(pshared)) {
cs->tag = 1;
}
}
SK.constraint.RemoveTagged();
} else {
// Make the original entities construction, or delete them
// entirely, according to user preference.
SK.GetRequest(hreq[0])->construction = true;
SK.GetRequest(hreq[1])->construction = true;
}

// Create and position the new tangent arc.
hRequest harc = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
Entity *earc = SK.GetEntity(harc.entity(0));
hEntity hearc = earc->h;
Expand All @@ -398,27 +438,11 @@ void GraphicsWindow::MakeTangentArc() {

earc = NULL;

pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
hent[0], hearc, /*arcFinish=*/(b == 1));
pc[1].CreateRequestTrimmedTo(t[1], !SS.tangentArcDeleteOld,
hent[1], hearc, /*arcFinish=*/(a == 1));

// Now either make the original entities construction, or delete them
// entirely, according to user preference.
Request *re;
SK.request.ClearTags();
for(re = SK.request.First(); re; re = SK.request.NextAfter(re)) {
if(re->h.v == hreq[0].v || re->h.v == hreq[1].v) {
if(SS.tangentArcDeleteOld) {
re->tag = 1;
} else {
re->construction = true;
}
}
}
if(SS.tangentArcDeleteOld) {
DeleteTaggedRequests();
}
// Modify or duplicate the original entities and connect them to the tangent arc.
pc[0].CreateRequestTrimmedTo(t[0], SS.tangentArcModify,
hent[0], hearc, /*arcFinish=*/(b == 1), pointf[0]);
pc[1].CreateRequestTrimmedTo(t[1], SS.tangentArcModify,
hent[1], hearc, /*arcFinish=*/(a == 1), pointf[1]);
}

hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
Expand Down
2 changes: 1 addition & 1 deletion src/solvespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ class SolveSpaceUI {
// as special requests.
double tangentArcRadius;
bool tangentArcManual;
bool tangentArcDeleteOld;
bool tangentArcModify;

// The platform-dependent code calls this before entering the msg loop
void Init();
Expand Down
6 changes: 3 additions & 3 deletions src/textscreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) {
}

case 'a': SS.tangentArcManual = !SS.tangentArcManual; break;
case 'd': SS.tangentArcDeleteOld = !SS.tangentArcDeleteOld; break;
case 'm': SS.tangentArcModify = !SS.tangentArcModify; break;
}
}
void TextWindow::ShowTangentArc() {
Expand All @@ -662,9 +662,9 @@ void TextWindow::ShowTangentArc() {
Printf(false, " %Fd%f%La%s choose radius automatically%E",
&ScreenChangeTangentArc,
!SS.tangentArcManual ? CHECK_TRUE : CHECK_FALSE);
Printf(false, " %Fd%f%Ld%s delete original entities afterward%E",
Printf(false, " %Fd%f%Lm%s modify original entities%E",
&ScreenChangeTangentArc,
SS.tangentArcDeleteOld ? CHECK_TRUE : CHECK_FALSE);
SS.tangentArcModify ? CHECK_TRUE : CHECK_FALSE);

Printf(false, "");
Printf(false, "To create a tangent arc at a point,");
Expand Down
7 changes: 4 additions & 3 deletions src/ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,8 +668,8 @@ class GraphicsWindow {
Vector TangentAt(double t);
double LengthForAuto();

hRequest CreateRequestTrimmedTo(double t, bool extraConstraints,
hEntity orig, hEntity arc, bool arcFinish);
void CreateRequestTrimmedTo(double t, bool reuseOrig,
hEntity orig, hEntity arc, bool arcFinish, bool pointf);
void ConstrainPointIfCoincident(hEntity hpt);
};
void MakeTangentArc();
Expand Down Expand Up @@ -718,6 +718,7 @@ class GraphicsWindow {
void HitTestMakeSelection(Point2d mp);
void ClearSelection();
void ClearNonexistentSelectionItems();
/// This structure is filled by a call to GroupSelection().
struct {
std::vector<hEntity> point;
std::vector<hEntity> entity;
Expand All @@ -740,7 +741,7 @@ class GraphicsWindow {
int stylables;
int constraintLabels;
int withEndpoints;
int n;
int n; ///< Number of selected items
} gs;
void GroupSelection();
bool IsSelected(Selection *s);
Expand Down

0 comments on commit f7a09e0

Please sign in to comment.