| 2712 | } |
| 2713 | |
| 2714 | void Space_Impl::intersectSurfaces(Space& other) { |
| 2715 | if (this->handle() == other.handle()) { |
| 2716 | return; |
| 2717 | } |
| 2718 | |
| 2719 | std::string name = nameString(); |
| 2720 | std::string otherName = other.nameString(); |
| 2721 | LOG(Debug, "Intersecting space " << name << " with space " << otherName); |
| 2722 | |
| 2723 | std::vector<Surface> surfaces = this->surfaces(); |
| 2724 | std::vector<Surface> otherSurfaces = other.surfaces(); |
| 2725 | |
| 2726 | std::sort(surfaces.begin(), surfaces.end(), [](const Surface& a, const Surface& b) -> bool { return a.grossArea() > b.grossArea(); }); |
| 2727 | std::sort(otherSurfaces.begin(), otherSurfaces.end(), [](const Surface& a, const Surface& b) -> bool { return a.grossArea() > b.grossArea(); }); |
| 2728 | |
| 2729 | std::map<std::string, bool> hasSubSurfaceMap; |
| 2730 | std::map<std::string, bool> hasAdjacentSurfaceMap; |
| 2731 | std::set<std::string> completedIntersections; |
| 2732 | |
| 2733 | bool anyNewSurfaces = true; |
| 2734 | while (anyNewSurfaces) { |
| 2735 | |
| 2736 | anyNewSurfaces = false; |
| 2737 | std::vector<Surface> newSurfaces; |
| 2738 | std::vector<Surface> newOtherSurfaces; |
| 2739 | |
| 2740 | for (Surface& surface : surfaces) { |
| 2741 | std::string surfaceHandle = toString(surface.handle()); |
| 2742 | |
| 2743 | if (hasSubSurfaceMap.find(surfaceHandle) == hasSubSurfaceMap.end()) { |
| 2744 | hasSubSurfaceMap[surfaceHandle] = !surface.subSurfaces().empty(); |
| 2745 | hasAdjacentSurfaceMap[surfaceHandle] = surface.adjacentSurface().has_value(); |
| 2746 | } |
| 2747 | |
| 2748 | if (hasSubSurfaceMap[surfaceHandle] || hasAdjacentSurfaceMap[surfaceHandle]) { |
| 2749 | continue; |
| 2750 | } |
| 2751 | |
| 2752 | for (Surface& otherSurface : otherSurfaces) { |
| 2753 | std::string otherSurfaceHandle = toString(otherSurface.handle()); |
| 2754 | |
| 2755 | if (hasSubSurfaceMap.find(otherSurfaceHandle) == hasSubSurfaceMap.end()) { |
| 2756 | hasSubSurfaceMap[otherSurfaceHandle] = !otherSurface.subSurfaces().empty(); |
| 2757 | hasAdjacentSurfaceMap[otherSurfaceHandle] = otherSurface.adjacentSurface().has_value(); |
| 2758 | } |
| 2759 | |
| 2760 | if (hasSubSurfaceMap[otherSurfaceHandle] || hasAdjacentSurfaceMap[otherSurfaceHandle]) { |
| 2761 | continue; |
| 2762 | } |
| 2763 | |
| 2764 | // see if we have already tested these for intersection, |
| 2765 | // surfaces that previously did not intersect will not intersect if vertices change |
| 2766 | // surfaces that previously did intersect will intersect exactly |
| 2767 | std::string intersectionKey = surfaceHandle + otherSurfaceHandle; |
| 2768 | if (completedIntersections.find(intersectionKey) != completedIntersections.end()) { |
| 2769 | continue; |
| 2770 | } |
| 2771 | completedIntersections.insert(intersectionKey); |