Allow removing spline points.
parent
2d25bdb51f
commit
77d8291216
|
@ -8,8 +8,8 @@
|
|||
#include "solvespace.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Replace a point-coincident constraint on oldpt with that same constraint
|
||||
// on newpt. Useful when splitting or tangent arcing.
|
||||
// Replace constraints on oldpt with the same constraints on newpt.
|
||||
// Useful when splitting, tangent arcing, or removing bezier points.
|
||||
//-----------------------------------------------------------------------------
|
||||
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
||||
int i;
|
||||
|
@ -23,6 +23,27 @@ void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
|||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Remove constraints on hpt. Useful when removing bezier points.
|
||||
//-----------------------------------------------------------------------------
|
||||
void GraphicsWindow::RemoveConstraintsForPointBeingDeleted(hEntity hpt) {
|
||||
SK.constraint.ClearTags();
|
||||
for(int i = 0; i < SK.constraint.n; i++) {
|
||||
Constraint *c = &(SK.constraint.elem[i]);
|
||||
if(c->ptA.v == hpt.v || c->ptB.v == hpt.v) {
|
||||
c->tag = 1;
|
||||
(SS.deleted.constraints)++;
|
||||
if(c->type != Constraint::POINTS_COINCIDENT &&
|
||||
c->type != Constraint::HORIZONTAL &&
|
||||
c->type != Constraint::VERTICAL)
|
||||
{
|
||||
(SS.deleted.nonTrivialConstraints)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SK.constraint.RemoveTagged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Let's say that A is coincident with B, and B is coincident with C. This
|
||||
// implies that A is coincident with C; but if we delete B, then both
|
||||
|
@ -67,9 +88,12 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
|
|||
c->tag = 1;
|
||||
}
|
||||
}
|
||||
// These would get removed anyways when we regenerated, but do it now;
|
||||
// that way subsequent calls of this function (if multiple coincident
|
||||
// points are getting deleted) will work correctly.
|
||||
// Remove constraints without waiting for regeneration; this way
|
||||
// if another point takes the place of the deleted one (e.g. when
|
||||
// removing control points of a bezier) the constraint doesn't
|
||||
// spuriously move. Similarly, subsequent calls of this function
|
||||
// (if multiple coincident points are getting deleted) will work
|
||||
// correctly.
|
||||
SK.constraint.RemoveTagged();
|
||||
|
||||
// If more than one point was constrained coincident with hpt, then
|
||||
|
|
|
@ -567,6 +567,18 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||
}
|
||||
if(gs.comments > 0 || gs.points > 0) {
|
||||
AddContextMenuItem("Snap to Grid", CMNU_SNAP_TO_GRID);
|
||||
|
||||
if(gs.points == 1) {
|
||||
hRequest hr = gs.point[0].request();
|
||||
if(hr.v != 0) {
|
||||
Request *r = SK.GetRequest(hr);
|
||||
int index = r->IndexOfPoint(gs.point[0]);
|
||||
if((r->type == Request::CUBIC && (index > 1 && index < r->extraPoints + 2)) ||
|
||||
r->type == Request::CUBIC_PERIODIC) {
|
||||
AddContextMenuItem("Remove Spline Point", CMNU_REMOVE_SPLINE_PT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(gs.points == 1) {
|
||||
|
@ -675,6 +687,36 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||
MenuEdit(MNU_SNAP_TO_GRID);
|
||||
break;
|
||||
|
||||
case CMNU_REMOVE_SPLINE_PT: {
|
||||
hRequest hr = gs.point[0].request();
|
||||
Request *r = SK.GetRequest(hr);
|
||||
|
||||
int index = r->IndexOfPoint(gs.point[0]);
|
||||
if(r->extraPoints == 0) oops();
|
||||
|
||||
SS.UndoRemember();
|
||||
Entity *e = SK.GetEntity(r->h.entity(0));
|
||||
|
||||
// First, fix point-coincident constraints involving this point.
|
||||
// Then, remove all other constraints, since they would otherwise
|
||||
// jump to an adjacent one and mess up the bezier after generation.
|
||||
FixConstraintsForPointBeingDeleted(e->point[index]);
|
||||
RemoveConstraintsForPointBeingDeleted(e->point[index]);
|
||||
|
||||
for(int i = index; i < MAX_POINTS_IN_ENTITY - 1; i++) {
|
||||
if(e->point[i + 1].v == 0) break;
|
||||
Entity *p0 = SK.GetEntity(e->point[i]);
|
||||
Entity *p1 = SK.GetEntity(e->point[i + 1]);
|
||||
ReplacePointInConstraints(p1->h, p0->h);
|
||||
p0->PointForceTo(p1->PointGetNum());
|
||||
}
|
||||
r->extraPoints--;
|
||||
SS.MarkGroupDirtyByEntity(gs.point[0]);
|
||||
SS.ScheduleGenerateAll();
|
||||
ClearSelection();
|
||||
break;
|
||||
}
|
||||
|
||||
case CMNU_GROUP_INFO: {
|
||||
hGroup hg;
|
||||
if(gs.entities == 1) {
|
||||
|
|
|
@ -184,6 +184,18 @@ std::string Request::DescriptionString(void) {
|
|||
return ssprintf("r%03x-%s", h.v, s);
|
||||
}
|
||||
|
||||
int Request::IndexOfPoint(hEntity he) {
|
||||
if(type == DATUM_POINT) {
|
||||
return (he.v == h.entity(0).v) ? 0 : -1;
|
||||
}
|
||||
for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) {
|
||||
if(he.v == h.entity(i + 1).v) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
hParam Request::AddParam(IdList<Param,hParam> *param, hParam hp) {
|
||||
Param pa = {};
|
||||
pa.h = hp;
|
||||
|
|
|
@ -299,6 +299,7 @@ public:
|
|||
void Generate(EntityList *entity, ParamList *param);
|
||||
|
||||
std::string DescriptionString(void);
|
||||
int IndexOfPoint(hEntity he);
|
||||
|
||||
void Clear(void) {}
|
||||
};
|
||||
|
|
2
src/ui.h
2
src/ui.h
|
@ -601,6 +601,7 @@ public:
|
|||
hEntity SplitCircle(hEntity he, Vector pinter);
|
||||
hEntity SplitCubic(hEntity he, Vector pinter);
|
||||
void ReplacePointInConstraints(hEntity oldpt, hEntity newpt);
|
||||
void RemoveConstraintsForPointBeingDeleted(hEntity hpt);
|
||||
void FixConstraintsForRequestBeingDeleted(hRequest hr);
|
||||
void FixConstraintsForPointBeingDeleted(hEntity hpt);
|
||||
|
||||
|
@ -678,6 +679,7 @@ public:
|
|||
CMNU_OTHER_ANGLE = 0x131,
|
||||
CMNU_DEL_COINCIDENT = 0x132,
|
||||
CMNU_SNAP_TO_GRID = 0x140,
|
||||
CMNU_REMOVE_SPLINE_PT = 0x141,
|
||||
CMNU_FIRST_STYLE = 0x40000000
|
||||
};
|
||||
void ContextMenuListStyles(void);
|
||||
|
|
Loading…
Reference in New Issue