KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drill_markers.cpp
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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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
21
22#include <trigo.h>
23
24
26{
27
28namespace
29{
30const unsigned char marker_patterns[MARKER_COUNT] = {
31
32 // Bit order is O Square Lozenge - | \ /
33 // Simple shapes first
34 0003, // X
35 0100, // O
36 0014, // +
37 0040, // Sq
38 0020, // Lz
39
40 // Two simple shapes
41 0103, // X O
42 0017, // X +
43 0043, // X Sq
44 0023, // X Lz
45 0114, // O +
46 0140, // O Sq
47 0120, // O Lz
48 0054, // + Sq
49 0034, // + Lz
50 0060, // Sq Lz
51
52 // Three simple shapes
53 0117, // X O +
54 0143, // X O Sq
55 0123, // X O Lz
56 0057, // X + Sq
57 0037, // X + Lz
58 0063, // X Sq Lz
59 0154, // O + Sq
60 0134, // O + Lz
61 0074, // + Sq Lz
62
63 // Four simple shapes
64 0174, // O Sq Lz +
65 0163, // X O Sq Lz
66 0157, // X O Sq +
67 0137, // X O Lz +
68 0077, // X Sq Lz +
69
70 // This draws *everything *
71 0177, // X O Sq Lz +
72
73 // Here we use the single bars... so the cross is forbidden
74 0110, // O -
75 0104, // O |
76 0101, // O /
77 0050, // Sq -
78 0044, // Sq |
79 0041, // Sq /
80 0030, // Lz -
81 0024, // Lz |
82 0021, // Lz /
83 0150, // O Sq -
84 0144, // O Sq |
85 0141, // O Sq /
86 0130, // O Lz -
87 0124, // O Lz |
88 0121, // O Lz /
89 0070, // Sq Lz -
90 0064, // Sq Lz |
91 0061, // Sq Lz /
92 0170, // O Sq Lz -
93 0164, // O Sq Lz |
94 0161, // O Sq Lz /
95
96 // The backlash component is the last resort, because it is easy to confound
97 0102, // \ O
98 0042, // \ Sq
99 0022, // \ Lz
100 0142, // \ O Sq
101 0122, // \ O Lz
102 0062, // \ Sq Lz
103 0162 // \ O Sq Lz
104 };
105
108const unsigned curated[] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 16 };
109
110
111void addSegment( std::vector<MARKER_PART>& aParts, const VECTOR2I& aStart, const VECTOR2I& aEnd )
112{
113 MARKER_PART part;
115 part.m_Points = { aStart, aEnd };
116 aParts.push_back( part );
117}
118
119
120void addPolyline( std::vector<MARKER_PART>& aParts, std::vector<VECTOR2I> aPoints )
121{
122 MARKER_PART part;
124 part.m_Points = std::move( aPoints );
125 aParts.push_back( part );
126}
127
128} // namespace
129
130
132{
133 return static_cast<int>( sizeof( curated ) / sizeof( curated[0] ) );
134}
135
136
137unsigned CuratedShape( int aIndex )
138{
139 if( aIndex < 0 || aIndex >= CuratedShapeCount() )
140 return 0;
141
142 return curated[aIndex];
143}
144
145
146std::vector<MARKER_PART> BuildMarker( const VECTOR2I& aPosition, int aRadius, unsigned aShapeId )
147{
148 std::vector<MARKER_PART> parts;
149
150 auto addCircle =
151 [&]()
152 {
153 MARKER_PART part;
155 part.m_Radius = aRadius;
156 parts.push_back( part );
157 };
158
159 if( aShapeId >= MARKER_COUNT )
160 {
161 addCircle();
162 return parts;
163 }
164
165 const unsigned char pat = marker_patterns[aShapeId];
166 const int r = aRadius;
167
168 if( pat & 0001 )
169 {
170 addSegment( parts, VECTOR2I( aPosition.x - r, aPosition.y - r ),
171 VECTOR2I( aPosition.x + r, aPosition.y + r ) );
172 }
173
174 if( pat & 0002 )
175 {
176 addSegment( parts, VECTOR2I( aPosition.x + r, aPosition.y - r ),
177 VECTOR2I( aPosition.x - r, aPosition.y + r ) );
178 }
179
180 if( pat & 0004 )
181 {
182 addSegment( parts, VECTOR2I( aPosition.x, aPosition.y - r ),
183 VECTOR2I( aPosition.x, aPosition.y + r ) );
184 }
185
186 if( pat & 0010 )
187 {
188 addSegment( parts, VECTOR2I( aPosition.x - r, aPosition.y ),
189 VECTOR2I( aPosition.x + r, aPosition.y ) );
190 }
191
192 if( pat & 0020 )
193 {
194 addPolyline( parts, { VECTOR2I( aPosition.x, aPosition.y + r ),
195 VECTOR2I( aPosition.x + r, aPosition.y ),
196 VECTOR2I( aPosition.x, aPosition.y - r ),
197 VECTOR2I( aPosition.x - r, aPosition.y ),
198 VECTOR2I( aPosition.x, aPosition.y + r ) } );
199 }
200
201 if( pat & 0040 )
202 {
203 // The square is inscribed in the marker circle, so its half-side is r/sqrt(2)
204 const int s = KiROUND( r / 1.4142 );
205
206 addPolyline( parts, { VECTOR2I( aPosition.x + s, aPosition.y + s ),
207 VECTOR2I( aPosition.x + s, aPosition.y - s ),
208 VECTOR2I( aPosition.x - s, aPosition.y - s ),
209 VECTOR2I( aPosition.x - s, aPosition.y + s ),
210 VECTOR2I( aPosition.x + s, aPosition.y + s ) } );
211 }
212
213 if( pat & 0100 )
214 addCircle();
215
216 return parts;
217}
218
219} // namespace DRILL_MARKERS
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:995
Drill marker outlines, as plain geometry.
unsigned CuratedShape(int aIndex)
Pattern index for the nth curated mark.
std::vector< MARKER_PART > BuildMarker(const VECTOR2I &aPosition, int aRadius, unsigned aShapeId)
Decompose one mark, in the order the parts must be drawn.
int CuratedShapeCount()
Marks that stay legible at chart size and in monochrome.
constexpr unsigned MARKER_COUNT
Total marks the pattern table can express.
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
One stroke of a mark.
std::vector< VECTOR2I > m_Points
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683