// Copyright 2025 The Manifold Authors.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314#include "tree2d.h"1516#include "parallel.h"1718#ifndef ZoneScoped19#if __has_include(<tracy/Tracy.hpp>)20#include <tracy/Tracy.hpp>21#else22#define FrameMarkStart(x)23#define FrameMarkEnd(x)24// putting ZoneScoped in a function will instrument the function execution when25// TRACY_ENABLE is set, which allows the profiler to record more accurate26// timing.27#define ZoneScoped28#define ZoneScopedN(name)29#endif30#endif3132namespace manifold {3334// Not really a proper KD-tree, but a kd tree with k = 2 and alternating x/y35// partition.36// Recursive sorting is not the most efficient, but simple and guaranteed to37// result in a balanced tree.38void BuildTwoDTreeImpl(VecView<PolyVert> points, bool sortX) {39auto cmpx = [](const PolyVert& a, const PolyVert& b) {40return a.pos.x < b.pos.x;41};42auto cmpy = [](const PolyVert& a, const PolyVert& b) {43return a.pos.y < b.pos.y;44};45if (sortX)46manifold::stable_sort(points.begin(), points.end(), cmpx);47else48manifold::stable_sort(points.begin(), points.end(), cmpy);49if (points.size() < 2) return;50BuildTwoDTreeImpl(points.view(0, points.size() / 2), !sortX);51BuildTwoDTreeImpl(points.view(points.size() / 2 + 1), !sortX);52}5354void BuildTwoDTree(VecView<PolyVert> points) {55ZoneScoped;56// don't even bother...57if (points.size() <= 8) return;58BuildTwoDTreeImpl(points, true);59}60} // namespace manifold616263