clipping via resubstitution
Open, Needs TriagePublic

Description

As there weren't sufficient FOSS to look up to for this purpose, most of it had to be implemented at least partially to have a good idea regarding it's feasibility. Most of the clipping algorithms work only with line segments. CGAL has implemented clipping for curves, but it requires monotonous curves. Greiner-Hormann is the only algorithm which is supposed to work for curves. However the original algorithm fails for common vertices and edges. An improved version exists, which was a bit more complex. But that algorithm also had a potential regression. Since there was a time constraint, this approach was not fully implemented, however it is partially done, where the points are stored in a vector (the point is inside KisClippingVertex, as it needs the types of intersections).

The second approach was to carry out the process by modifying Qt's original algorithm. The file kispathclipper.cpp is a copy of qpathclipper.cpp and contains all of the code required for clipping using Qt;s approach. The basic idea was to mark the segments while flattening the curves (in QWingedEdge::addPath), and then to restore the curves again when the WingedEdge structure is converted back to QPainterPath. The code is implemented. However, I was not able to fully implement it. The code was complex, and was largely undocumented. I have implemented the marking and substitution process. However, there seems to be a bug introduced which causes the shapes to be improperly clipped. the fault mostly lies in the functions QWingedEdge::doClip and handleCrossingEdges, but I was not able to debug it properly in time. However, I have documented Qt's code to the best of my capacity, and I hope it will quicken the process of understanding it's algorithm.

The final and current approach is to carry out the substitution routine outside Qt's clipping algorithm. Fortunately, this can be done without losing any accuracy. After finding all points of intersection, we process the shapes to convert all points of intersection to regular vertices (in the function KisIntersectionFinder::processShapes.) This ensures there are no unaccounted intersection points remaining. Due to this, Qt will carry it's clipping routine purely using the common vertices and no intersection points, leading to clipping purely based on vertices, and no loss of accuracy.

The resubstitution is carried out in the function KisIntersectionFinder::resubstituteCurves. The logic is pretty simple. In the shape processing function, we record all of the endpoints of curves. Then, we parse the clipped shapes to find the flattened curves and replace them with the original curves. The current implementation does it well for union and intersection operations. It seems to fail for the difference operation. I'm still working on it, and it seems to work correctly for the most part, and should be able to cover all bases soon.