diff --git a/graphicswin.cpp b/graphicswin.cpp index 0990332..72945e1 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -558,6 +558,14 @@ void GraphicsWindow::ForceTextWindowShown(void) { } void GraphicsWindow::DeleteTaggedRequests(void) { + // Rewrite any point-coincident constraints that were affected by this + // deletion. + Request *r; + for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) { + if(!r->tag) continue; + FixConstraintsForRequestBeingDeleted(r->h); + } + // and then delete the tagged requests. SK.request.RemoveTagged(); // An edit might be in progress for the just-deleted item. So diff --git a/modify.cpp b/modify.cpp index 184cf3b..e5b0746 100644 --- a/modify.cpp +++ b/modify.cpp @@ -16,6 +16,62 @@ void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) { } } + +void GraphicsWindow::FixConstraintsForRequestBeingDeleted(hRequest hr) { + Request *r = SK.GetRequest(hr); + if(r->group.v != SS.GW.activeGroup.v) return; + + Entity *e; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(!(e->h.isFromRequest())) continue; + if(e->h.request().v != hr.v) continue; + + if(e->type != Entity::POINT_IN_2D && + e->type != Entity::POINT_IN_3D) + { + continue; + } + + // This is a point generated by the request being deleted; so fix + // the constraints for that. + FixConstraintsForPointBeingDeleted(e->h); + } +} +void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) { + List ld; + ZERO(&ld); + + Constraint *c; + SK.constraint.ClearTags(); + for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { + if(c->type != Constraint::POINTS_COINCIDENT) continue; + if(c->group.v != SS.GW.activeGroup.v) continue; + + if(c->ptA.v == hpt.v) { + ld.Add(&(c->ptB)); + c->tag = 1; + } + if(c->ptB.v == hpt.v) { + ld.Add(&(c->ptA)); + 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. + SK.constraint.RemoveTagged(); + + // If more than one point was constrained coincident with hpt, then + // those two points were implicitly coincident with each other. By + // deleting hpt (and all constraints that mention it), we will delete + // that relationship. So put it back here now. + int i; + for(i = 1; i < ld.n; i++) { + Constraint::ConstrainCoincident(ld.elem[i-1], ld.elem[i]); + } + ld.Clear(); +} + //----------------------------------------------------------------------------- // A single point must be selected when this function is called. We find two // non-construction line segments that join at this point, and create a @@ -273,7 +329,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) { SK.GetEntity(ei1->point[3])->PointForceTo(bi1.ctrl[3]); ReplacePointInConstraints(hep0, e0i->point[0]); - ReplacePointInConstraints(hep1, ei1->point[3]); + ReplacePointInConstraints(hep3, ei1->point[3]); Constraint::ConstrainCoincident(e0i->point[3], ei1->point[0]); return e0i->point[3]; } diff --git a/ui.h b/ui.h index e68421f..0f6ce35 100644 --- a/ui.h +++ b/ui.h @@ -352,6 +352,8 @@ public: hEntity SplitCircle(hEntity he, Vector pinter); hEntity SplitCubic(hEntity he, Vector pinter); void ReplacePointInConstraints(hEntity oldpt, hEntity newpt); + void FixConstraintsForRequestBeingDeleted(hRequest hr); + void FixConstraintsForPointBeingDeleted(hEntity hpt); // The current selection. class Selection {