I'm against the idea that people should be attached to "their" code (that is: the code they wrote). Now I also understand that humans that humans, but the priority should be to make them evolve toward more detachment from their work and acceptance that what they design "can" (actually will) be imperfect, rather than avoiding upsetting them even when it would not be justified to be upset. Plus one essential purpose of source control is to be able to make changes, and revert them if they were "wrong"; or for any other purpose. Maybe propose a patch instead of committing directly, but that's really a cultural matter about how projects are organized.
I don't want to ask of permission for an improvement. If there is a need to have formal authorization of maintainers responsible for parts of the code, they setup just that. Otherwise, I'm certainly going to improve "your" code, in some rare cases without even telling you (that's not a goal in itself to do it behind your back, obviously, and I also value collaboration -- but that should not be a problem). The question that remains is: is it really an improvement. If you are not sure, then maybe don't commit. If you are, do it (following your local rules), and if it ends up being a mistake, yes, it will be reverted, and so what?
You should not take issue of your work being reverted (for good reasons), like other people should not take issue of "their" code being modified. Better ask for forgiveness than permission.
> For example, we later needed many special cases and behaviors for different handles on different shapes. My abstraction would have to become several times more convoluted to afford that, whereas with the original “messy” version such changes stayed easy as cake.
Then re-expand the code later.