Allow removing spline points.
This commit is contained in:
parent
2d25bdb51f
commit
77d8291216
@ -8,8 +8,8 @@
|
|||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Replace a point-coincident constraint on oldpt with that same constraint
|
// Replace constraints on oldpt with the same constraints on newpt.
|
||||||
// on newpt. Useful when splitting or tangent arcing.
|
// Useful when splitting, tangent arcing, or removing bezier points.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
||||||
int i;
|
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
|
// 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
|
// 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;
|
c->tag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// These would get removed anyways when we regenerated, but do it now;
|
// Remove constraints without waiting for regeneration; this way
|
||||||
// that way subsequent calls of this function (if multiple coincident
|
// if another point takes the place of the deleted one (e.g. when
|
||||||
// points are getting deleted) will work correctly.
|
// 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();
|
SK.constraint.RemoveTagged();
|
||||||
|
|
||||||
// If more than one point was constrained coincident with hpt, then
|
// 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) {
|
if(gs.comments > 0 || gs.points > 0) {
|
||||||
AddContextMenuItem("Snap to Grid", CMNU_SNAP_TO_GRID);
|
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) {
|
if(gs.points == 1) {
|
||||||
@ -675,6 +687,36 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||||||
MenuEdit(MNU_SNAP_TO_GRID);
|
MenuEdit(MNU_SNAP_TO_GRID);
|
||||||
break;
|
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: {
|
case CMNU_GROUP_INFO: {
|
||||||
hGroup hg;
|
hGroup hg;
|
||||||
if(gs.entities == 1) {
|
if(gs.entities == 1) {
|
||||||
|
@ -184,6 +184,18 @@ std::string Request::DescriptionString(void) {
|
|||||||
return ssprintf("r%03x-%s", h.v, s);
|
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) {
|
hParam Request::AddParam(IdList<Param,hParam> *param, hParam hp) {
|
||||||
Param pa = {};
|
Param pa = {};
|
||||||
pa.h = hp;
|
pa.h = hp;
|
||||||
|
@ -299,6 +299,7 @@ public:
|
|||||||
void Generate(EntityList *entity, ParamList *param);
|
void Generate(EntityList *entity, ParamList *param);
|
||||||
|
|
||||||
std::string DescriptionString(void);
|
std::string DescriptionString(void);
|
||||||
|
int IndexOfPoint(hEntity he);
|
||||||
|
|
||||||
void Clear(void) {}
|
void Clear(void) {}
|
||||||
};
|
};
|
||||||
|
2
src/ui.h
2
src/ui.h
@ -601,6 +601,7 @@ public:
|
|||||||
hEntity SplitCircle(hEntity he, Vector pinter);
|
hEntity SplitCircle(hEntity he, Vector pinter);
|
||||||
hEntity SplitCubic(hEntity he, Vector pinter);
|
hEntity SplitCubic(hEntity he, Vector pinter);
|
||||||
void ReplacePointInConstraints(hEntity oldpt, hEntity newpt);
|
void ReplacePointInConstraints(hEntity oldpt, hEntity newpt);
|
||||||
|
void RemoveConstraintsForPointBeingDeleted(hEntity hpt);
|
||||||
void FixConstraintsForRequestBeingDeleted(hRequest hr);
|
void FixConstraintsForRequestBeingDeleted(hRequest hr);
|
||||||
void FixConstraintsForPointBeingDeleted(hEntity hpt);
|
void FixConstraintsForPointBeingDeleted(hEntity hpt);
|
||||||
|
|
||||||
@ -678,6 +679,7 @@ public:
|
|||||||
CMNU_OTHER_ANGLE = 0x131,
|
CMNU_OTHER_ANGLE = 0x131,
|
||||||
CMNU_DEL_COINCIDENT = 0x132,
|
CMNU_DEL_COINCIDENT = 0x132,
|
||||||
CMNU_SNAP_TO_GRID = 0x140,
|
CMNU_SNAP_TO_GRID = 0x140,
|
||||||
|
CMNU_REMOVE_SPLINE_PT = 0x141,
|
||||||
CMNU_FIRST_STYLE = 0x40000000
|
CMNU_FIRST_STYLE = 0x40000000
|
||||||
};
|
};
|
||||||
void ContextMenuListStyles(void);
|
void ContextMenuListStyles(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user