Now add the self-intersection check after ring assembly, filtering out invalid rings.


658:            if (ring.size() >= 4) {

658:            if (ring.size() >= 4) {


   655→                    }
   656→                }
   657→            }
   658→            if (ring.size() >= 4) {
   659→                rings.push_back(std::move(ring));
   660→            }
   661→        } else {
   662→            used[start_idx] = false;
   663→        }
   664→    }

                    }
                }
            }
            if (ring.size() >= 4) {
                rings.push_back(std::move(ring));
            }
        } else {
            used[start_idx] = false;
        }
    }


Edit

            if (ring.size() >= 4) {
                rings.push_back(std::move(ring));
            }
        } else {
            used[start_idx] = false;
        }
    }

            if (ring.size() >= 4 && !ring_has_self_intersection(ring)) {
                rings.push_back(std::move(ring));
            }
        } else {
            used[start_idx] = false;
        }
    }