Skip to content

Commit

Permalink
Merge b75bfea into 8426992
Browse files Browse the repository at this point in the history
  • Loading branch information
bcmpinc committed Jul 24, 2018
2 parents 8426992 + b75bfea commit dae5f9b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 49 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -88,6 +88,8 @@ Bugs fixed:
* A step rotate/translate group using a group forced to triangle mesh
as a source group also gets forced to triangle mesh.
* Paste Transformed with a negative scale does not invert arcs.
* The tangent arc now modifies the original entities instead of deleting
them, such that their constraints are retained.

2.x
---
Expand Down
108 changes: 66 additions & 42 deletions src/modify.cpp
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
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
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
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 dae5f9b

Please sign in to comment.