Allow adding spline points.
parent
77d8291216
commit
16ea824456
|
@ -17,7 +17,7 @@ std::string Entity::DescriptionString(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat) {
|
void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat, int data) {
|
||||||
if(dogd.drawing) {
|
if(dogd.drawing) {
|
||||||
// Draw lines from active group in front of those from previous
|
// Draw lines from active group in front of those from previous
|
||||||
ssglDepthRangeOffset((group.v == SS.GW.activeGroup.v) ? 4 : 3);
|
ssglDepthRangeOffset((group.v == SS.GW.activeGroup.v) ? 4 : 3);
|
||||||
|
@ -32,7 +32,10 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat) {
|
||||||
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), true);
|
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), true);
|
||||||
// A little bit easier to select in the active group
|
// A little bit easier to select in the active group
|
||||||
if(group.v == SS.GW.activeGroup.v) d -= 1;
|
if(group.v == SS.GW.activeGroup.v) d -= 1;
|
||||||
dogd.dmin = min(dogd.dmin, d);
|
if(d < dogd.dmin) {
|
||||||
|
dogd.dmin = d;
|
||||||
|
dogd.data = data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dogd.refp = (a.Plus(b)).ScaledBy(0.5);
|
dogd.refp = (a.Plus(b)).ScaledBy(0.5);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +130,7 @@ void Entity::GenerateEdges(SEdgeList *el, bool includingConstruction) {
|
||||||
List<Vector> lv = {};
|
List<Vector> lv = {};
|
||||||
sb->MakePwlInto(&lv);
|
sb->MakePwlInto(&lv);
|
||||||
for(j = 1; j < lv.n; j++) {
|
for(j = 1; j < lv.n; j++) {
|
||||||
el->AddEdge(lv.elem[j-1], lv.elem[j], style.v);
|
el->AddEdge(lv.elem[j-1], lv.elem[j], style.v, i);
|
||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
@ -707,10 +710,10 @@ void Entity::DrawOrGetDistance(void) {
|
||||||
// And draw the curves; generate the rational polynomial curves for
|
// And draw the curves; generate the rational polynomial curves for
|
||||||
// everything, then piecewise linearize them, and display those.
|
// everything, then piecewise linearize them, and display those.
|
||||||
SEdgeList *sel = GetOrGenerateEdges();
|
SEdgeList *sel = GetOrGenerateEdges();
|
||||||
int i;
|
dogd.data = -1;
|
||||||
for(i = 0; i < sel->l.n; i++) {
|
for(int i = 0; i < sel->l.n; i++) {
|
||||||
SEdge *se = &(sel->l.elem[i]);
|
SEdge *se = &(sel->l.elem[i]);
|
||||||
LineDrawOrGetDistance(se->a, se->b, true);
|
LineDrawOrGetDistance(se->a, se->b, true, se->auxB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,8 @@ void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(i = 0; i < SK.constraint.n; i++) {
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
Constraint *c = &(SK.constraint.elem[i]);
|
||||||
|
if(c->ptA.v == oldpt.v) c->ptA = newpt;
|
||||||
if(c->type == Constraint::POINTS_COINCIDENT) {
|
if(c->ptB.v == oldpt.v) c->ptB = newpt;
|
||||||
if(c->ptA.v == oldpt.v) c->ptA = newpt;
|
|
||||||
if(c->ptB.v == oldpt.v) c->ptB = newpt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -528,6 +528,11 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The current mouse location
|
||||||
|
Vector v = offset.ScaledBy(-1);
|
||||||
|
v = v.Plus(projRight.ScaledBy(x/scale));
|
||||||
|
v = v.Plus(projUp.ScaledBy(y/scale));
|
||||||
|
|
||||||
context.active = true;
|
context.active = true;
|
||||||
|
|
||||||
if(!hover.IsEmpty()) {
|
if(!hover.IsEmpty()) {
|
||||||
|
@ -537,6 +542,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
GroupSelection();
|
GroupSelection();
|
||||||
|
|
||||||
bool itemsSelected = (gs.n > 0 || gs.constraints > 0);
|
bool itemsSelected = (gs.n > 0 || gs.constraints > 0);
|
||||||
|
int addAfterPoint = -1;
|
||||||
|
|
||||||
if(itemsSelected) {
|
if(itemsSelected) {
|
||||||
if(gs.stylables > 0) {
|
if(gs.stylables > 0) {
|
||||||
|
@ -581,6 +587,22 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(gs.entities == 1) {
|
||||||
|
hRequest hr = gs.entity[0].request();
|
||||||
|
if(hr.v != 0) {
|
||||||
|
Request *r = SK.GetRequest(hr);
|
||||||
|
if(r->type == Request::CUBIC || r->type == Request::CUBIC_PERIODIC) {
|
||||||
|
Entity *e = SK.GetEntity(gs.entity[0]);
|
||||||
|
e->GetDistance(Point2d::From(x, y));
|
||||||
|
addAfterPoint = e->dogd.data;
|
||||||
|
if(addAfterPoint == -1) oops();
|
||||||
|
// Skip derivative point.
|
||||||
|
if(r->type == Request::CUBIC) addAfterPoint++;
|
||||||
|
AddContextMenuItem("Add Spline Point", CMNU_ADD_SPLINE_PT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(gs.points == 1) {
|
if(gs.points == 1) {
|
||||||
Entity *p = SK.GetEntity(gs.point[0]);
|
Entity *p = SK.GetEntity(gs.point[0]);
|
||||||
Constraint *c;
|
Constraint *c;
|
||||||
|
@ -717,6 +739,36 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CMNU_ADD_SPLINE_PT: {
|
||||||
|
hRequest hr = gs.entity[0].request();
|
||||||
|
Request *r = SK.GetRequest(hr);
|
||||||
|
|
||||||
|
int pointCount = r->extraPoints + ((r->type == Request::CUBIC_PERIODIC) ? 3 : 4);
|
||||||
|
if(pointCount < MAX_POINTS_IN_ENTITY) {
|
||||||
|
SS.UndoRemember();
|
||||||
|
r->extraPoints++;
|
||||||
|
SS.MarkGroupDirtyByEntity(gs.entity[0]);
|
||||||
|
SS.GenerateAll(SolveSpaceUI::GENERATE_REGEN);
|
||||||
|
|
||||||
|
Entity *e = SK.GetEntity(r->h.entity(0));
|
||||||
|
for(int i = MAX_POINTS_IN_ENTITY; i > addAfterPoint + 1; i--) {
|
||||||
|
Entity *p0 = SK.entity.FindByIdNoOops(e->point[i]);
|
||||||
|
if(p0 == NULL) continue;
|
||||||
|
Entity *p1 = SK.GetEntity(e->point[i - 1]);
|
||||||
|
ReplacePointInConstraints(p1->h, p0->h);
|
||||||
|
p0->PointForceTo(p1->PointGetNum());
|
||||||
|
}
|
||||||
|
Entity *p = SK.GetEntity(e->point[addAfterPoint + 1]);
|
||||||
|
p->PointForceTo(v);
|
||||||
|
SS.MarkGroupDirtyByEntity(gs.entity[0]);
|
||||||
|
SS.ScheduleGenerateAll();
|
||||||
|
ClearSelection();
|
||||||
|
} else {
|
||||||
|
Error("Cannot add spline point: maximum number of points reached.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CMNU_GROUP_INFO: {
|
case CMNU_GROUP_INFO: {
|
||||||
hGroup hg;
|
hGroup hg;
|
||||||
if(gs.entities == 1) {
|
if(gs.entities == 1) {
|
||||||
|
|
|
@ -492,8 +492,9 @@ public:
|
||||||
double lineWidth;
|
double lineWidth;
|
||||||
double stippleScale;
|
double stippleScale;
|
||||||
int stippleType;
|
int stippleType;
|
||||||
|
int data;
|
||||||
} dogd; // state for drawing or getting distance (for hit testing)
|
} dogd; // state for drawing or getting distance (for hit testing)
|
||||||
void LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat=false);
|
void LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat=false, int userData = -1);
|
||||||
void DrawOrGetDistance(void);
|
void DrawOrGetDistance(void);
|
||||||
|
|
||||||
bool IsStylable();
|
bool IsStylable();
|
||||||
|
|
1
src/ui.h
1
src/ui.h
|
@ -680,6 +680,7 @@ public:
|
||||||
CMNU_DEL_COINCIDENT = 0x132,
|
CMNU_DEL_COINCIDENT = 0x132,
|
||||||
CMNU_SNAP_TO_GRID = 0x140,
|
CMNU_SNAP_TO_GRID = 0x140,
|
||||||
CMNU_REMOVE_SPLINE_PT = 0x141,
|
CMNU_REMOVE_SPLINE_PT = 0x141,
|
||||||
|
CMNU_ADD_SPLINE_PT = 0x142,
|
||||||
CMNU_FIRST_STYLE = 0x40000000
|
CMNU_FIRST_STYLE = 0x40000000
|
||||||
};
|
};
|
||||||
void ContextMenuListStyles(void);
|
void ContextMenuListStyles(void);
|
||||||
|
|
Loading…
Reference in New Issue