KiCad PCB EDA Suite
Loading...
Searching...
No Matches
segment_index.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef SEGMENT_INDEX_H
21#define SEGMENT_INDEX_H
22
24#include <geometry/seg.h>
25
26#include <algorithm>
27#include <cstdint>
28#include <limits>
29#include <utility>
30#include <vector>
31
32
41{
42public:
43 explicit SEGMENT_INDEX( std::vector<SEG> aSegments ) :
44 m_segments( std::move( aSegments ) )
45 {
46 TREE::Builder builder;
47 builder.Reserve( m_segments.size() );
48
49 for( size_t i = 0; i < m_segments.size(); ++i )
50 {
51 const SEG& segment = m_segments[i];
52 const int min[2] = { std::min( segment.A.x, segment.B.x ), std::min( segment.A.y, segment.B.y ) };
53 const int max[2] = { std::max( segment.A.x, segment.B.x ), std::max( segment.A.y, segment.B.y ) };
54 builder.Add( min, max, static_cast<int>( i ) );
55 }
56
57 m_tree = builder.Build();
58 }
59
60 SEGMENT_INDEX( SEGMENT_INDEX&& ) noexcept = default;
61 SEGMENT_INDEX& operator=( SEGMENT_INDEX&& ) noexcept = default;
62 SEGMENT_INDEX( const SEGMENT_INDEX& ) = delete;
63 SEGMENT_INDEX& operator=( const SEGMENT_INDEX& ) = delete;
64
65 size_t size() const { return m_segments.size(); }
66
67 const SEG& Segment( int aIndex ) const { return m_segments[aIndex]; }
68
76 template <typename VISITOR>
77 void VisitCandidates( const SEG& aQuery, int aPadding, VISITOR&& aVisitor ) const
78 {
79 const int64_t padding = std::max( aPadding, 0 );
80 const int64_t minX = static_cast<int64_t>( std::min( aQuery.A.x, aQuery.B.x ) ) - padding;
81 const int64_t minY = static_cast<int64_t>( std::min( aQuery.A.y, aQuery.B.y ) ) - padding;
82 const int64_t maxX = static_cast<int64_t>( std::max( aQuery.A.x, aQuery.B.x ) ) + padding;
83 const int64_t maxY = static_cast<int64_t>( std::max( aQuery.A.y, aQuery.B.y ) ) + padding;
84 const int min[2] = { clampCoordinate( minX ), clampCoordinate( minY ) };
85 const int max[2] = { clampCoordinate( maxX ), clampCoordinate( maxY ) };
86 m_tree.Search( min, max, aVisitor );
87 }
88
89private:
91
92 static int clampCoordinate( int64_t aValue )
93 {
94 return static_cast<int>( std::clamp( aValue, static_cast<int64_t>( std::numeric_limits<int>::min() ),
95 static_cast<int64_t>( std::numeric_limits<int>::max() ) ) );
96 }
97
98 std::vector<SEG> m_segments;
100};
101
102#endif // SEGMENT_INDEX_H
Static (immutable) packed R-tree built via Hilbert-curve bulk loading.
void VisitCandidates(const SEG &aQuery, int aPadding, VISITOR &&aVisitor) const
Visit candidates overlapping aQuery's endpoint bounds expanded by aPadding.
static int clampCoordinate(int64_t aValue)
std::vector< SEG > m_segments
const SEG & Segment(int aIndex) const
SEGMENT_INDEX(std::vector< SEG > aSegments)
size_t size() const
SEGMENT_INDEX(SEGMENT_INDEX &&) noexcept=default
KIRTREE::PACKED_RTREE< int, int, 2 > TREE
Definition seg.h:38
VECTOR2I A
Definition seg.h:45
VECTOR2I B
Definition seg.h:46
STL namespace.