KiCad PCB EDA Suite
Loading...
Searching...
No Matches
odb_feature.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 * Author: SYSUEric <[email protected]>.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21
22#pragma once
23
24#include "odb_attribute.h"
25#include "odb_util.h"
27
28#include <iterator>
29#include <list>
30#include <optional>
31#include <math/vector2d.h>
32#include <common.h>
33#include "odb_defines.h"
34
35
36enum class ODB_DIRECTION
37{
40};
41
42
43class ODB_LINE;
44class ODB_ARC;
45class ODB_PAD;
46class ODB_SURFACE;
47class ODB_FEATURE;
48class PCB_IO_ODBPP;
49class FOOTPRINT;
50class PAD;
51class PCB_VIA;
53class PCB_TRACK;
54
56{
57public:
58 FEATURES_MANAGER( BOARD* aBoard, PCB_IO_ODBPP* aPlugin, const wxString& aLayerName, ODB_LAYER_ROLE aRole,
59 std::optional<ODB_AUX_LAYER_TYPE> aAuxType,
60 std::optional<DRILL_SPAN> aDrillSpan = std::nullopt ) :
61 m_board( aBoard ),
62 m_plugin( aPlugin ),
63 m_layerName( aLayerName ),
64 m_role( aRole ),
65 m_auxType( aAuxType ),
66 m_drillSpan( aDrillSpan )
67 {}
68
69 void AddPad( PCB_LAYER_ID aLayer, PAD* pad );
70 void AddDimension( PCB_LAYER_ID aLayer, PCB_DIMENSION_BASE* dimension );
71 void AddShape( PCB_LAYER_ID aLayer, PCB_SHAPE* shape );
72 void AddText( PCB_LAYER_ID aLayer, BOARD_ITEM* item, RESOLUTION_CONTEXT aContext );
73 void AddZone( PCB_LAYER_ID aLayer, ZONE* zone );
74 void AddTrack( PCB_LAYER_ID aLayer, PCB_TRACK* track );
75
76 void InitFeatureList( PCB_LAYER_ID aLayer, const std::vector<BOARD_ITEM*>& aItems );
77
78 void AddFeatureLine( const VECTOR2I& aStart, const VECTOR2I& aEnd, uint64_t aWidth );
79
80 void AddFeatureArc( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCenter,
81 uint64_t aWidth, ODB_DIRECTION aDirection );
82
83 void AddRoutContour( const SHAPE_LINE_CHAIN& aContour, int aChain, bool aPlated );
84 void AddRoutSlot( const PAD& aPad, int aChain );
85
86 void AddPadCircle( const VECTOR2I& aCenter, uint64_t aDiameter );
87
88 void AddPadShape( const PAD& aPad, PCB_LAYER_ID aLayer );
89
90 bool AddFeatureSurface( const SHAPE_POLY_SET::POLYGON& aPolygon, FILL_T aFillType = FILL_T::FILLED_SHAPE );
91
92 size_t FeatureCount() const { return m_featuresList.size(); }
93
94 void AddShape( const PCB_SHAPE& aShape, PCB_LAYER_ID aLayer = UNDEFINED_LAYER );
95
96 void AddVia( const PCB_VIA* aVia, PCB_LAYER_ID aLayer );
97
98 bool AddViaDrillHole( const PCB_VIA* aVia, PCB_LAYER_ID aLayer );
99
100 void AddViaProtection( const PCB_VIA* aVia, bool drill, PCB_LAYER_ID aLayer );
101
102 bool AddContour( const SHAPE_POLY_SET& aPolySet, int aOutline = 0,
103 FILL_T aFillType = FILL_T::FILLED_SHAPE );
104
105 bool AddPolygon( const SHAPE_POLY_SET::POLYGON& aPolygon, FILL_T aFillType, int aWidth,
106 LINE_STYLE aDashType );
107
109
110 void GenerateFeatureFile( std::ostream& ost ) const;
111
112 void GenerateProfileFeatures( std::ostream& ost ) const;
113
114private:
115 inline uint32_t AddCircleSymbol( const wxString& aDiameter )
116 {
117 return GetSymbolIndex( m_circleSymMap, "r" + aDiameter );
118 }
119
120 uint32_t AddRoundDonutSymbol( const wxString& aOuterDim, const wxString& aInnerDim )
121 {
122 wxString sym = "donut_r" + aOuterDim + ODB_DIM_X + aInnerDim;
123 return GetSymbolIndex( m_roundDonutSymMap, sym );
124 }
125
126 uint32_t AddRectSymbol( const wxString& aWidth, const wxString& aHeight )
127 {
128 wxString sym = "rect" + aWidth + ODB_DIM_X + aHeight;
129 return GetSymbolIndex( m_rectSymMap, sym );
130 }
131
132 uint32_t AddOvalSymbol( const wxString& aWidth, const wxString& aHeight )
133 {
134 wxString sym = "oval" + aWidth + ODB_DIM_X + aHeight;
135 return GetSymbolIndex( m_ovalSymMap, sym );
136 }
137
138 uint32_t AddRoundRectSymbol( const wxString& aWidth, const wxString& aHeight,
139 const wxString& aRadius )
140 {
141 wxString sym = "rect" + aWidth + ODB_DIM_X + aHeight + ODB_DIM_X + ODB_DIM_R + aRadius;
142 return GetSymbolIndex( m_roundRectSymMap, sym );
143 }
144
145 uint32_t AddRoundRectDonutSymbol( const wxString& aOuterWidth, const wxString& aOuterHeight,
146 const wxString& aLineWidth, const wxString& aRadius )
147 {
148 wxString sym = "donut_rc" + aOuterWidth + ODB_DIM_X + aOuterHeight + ODB_DIM_X + aLineWidth
149 + ODB_DIM_X + ODB_DIM_R + aRadius;
151 }
152
153 uint32_t AddChamferRectSymbol( const wxString& aWidth, const wxString& aHeight,
154 const wxString& aRadius, int aPositions )
155 {
156 wxString sym = "rect" + aWidth + ODB_DIM_X + aHeight + ODB_DIM_X + ODB_DIM_C + aRadius;
157
158 if( aPositions != RECT_CHAMFER_ALL )
159 {
160 sym += ODB_DIM_X;
161 if( aPositions & RECT_CHAMFER_TOP_RIGHT )
162 sym += "1";
163 if( aPositions & RECT_CHAMFER_TOP_LEFT )
164 sym += "2";
165 if( aPositions & RECT_CHAMFER_BOTTOM_LEFT )
166 sym += "3";
167 if( aPositions & RECT_CHAMFER_BOTTOM_RIGHT )
168 sym += "4";
169 }
170
171 return GetSymbolIndex( m_chamRectSymMap, sym );
172 }
173
174
175 uint32_t GetSymbolIndex( std::map<wxString, uint32_t>& aSymMap, const wxString& aKey )
176 {
177 if( aSymMap.count( aKey ) )
178 {
179 return aSymMap.at( aKey );
180 }
181 else
182 {
183 uint32_t index = m_symIndex;
184 m_symIndex++;
185 aSymMap.emplace( aKey, index );
186 m_allSymMap.emplace( index, aKey );
187 return index;
188 }
189 }
190
191 void tagRoutFeatures( size_t aFirst, int aChain, bool aPlated );
192 void addViaDrillAttributes( ODB_FEATURE& aFeature, const PCB_VIA* aVia );
193 void addPostMachiningAttributes( ODB_FEATURE& aFeature, const DRILL_OPERATION& aOperation );
194
195 std::map<wxString, uint32_t> m_circleSymMap; // diameter -> symbol index
196 std::map<wxString, uint32_t> m_roundDonutSymMap;
197 std::map<wxString, uint32_t> m_padSymMap; // name -> symbol index
198 std::map<wxString, uint32_t> m_rectSymMap; // w,h -> symbol index
199 std::map<wxString, uint32_t> m_ovalSymMap; // w,h -> symbol index
200 std::map<wxString, uint32_t> m_roundRectSymMap;
201 std::map<wxString, uint32_t> m_roundRectDonutSymMap;
202 std::map<wxString, uint32_t> m_chamRectSymMap;
203
204 std::map<uint32_t, wxString> m_allSymMap;
205
206 template <typename T, typename... Args>
207 void AddFeature( Args&&... args )
208 {
209 auto feature = std::make_unique<T>( m_featuresList.size(), std::forward<Args>( args )... );
210
211 m_featuresList.emplace_back( std::move( feature ) );
212 }
213
214 template <typename F>
215 void forEachNewFeature( size_t aFirst, F&& aFunc )
216 {
217 auto it = std::prev( m_featuresList.end(), m_featuresList.size() - aFirst );
218
219 for( size_t index = aFirst; it != m_featuresList.end(); ++it, ++index )
220 aFunc( **it, index );
221 }
222
223 inline PCB_IO_ODBPP* GetODBPlugin() { return m_plugin; }
224
227 wxString m_layerName;
229 std::optional<ODB_AUX_LAYER_TYPE> m_auxType;
230 std::optional<DRILL_SPAN> m_drillSpan;
231 uint32_t m_symIndex = 0;
232
233 std::list<std::unique_ptr<ODB_FEATURE>> m_featuresList;
234};
235
236
238{
239public:
240 // template <typename T> using check_type = attribute::is_feature<T>;
241 ODB_FEATURE( uint32_t aIndex ) : m_index( aIndex ) {}
242 virtual void WriteFeatures( std::ostream& ost, const ODB_FORMAT& aFormat );
243
244 virtual ~ODB_FEATURE() = default;
245
246protected:
247 enum class FEATURE_TYPE
248 {
253 };
254
256
257 virtual void WriteRecordContent( std::ostream& ost, const ODB_FORMAT& aFormat ) = 0;
258
259 const uint32_t m_index;
260};
261
262class ODB_LINE : public ODB_FEATURE
263{
264public:
265 ODB_LINE( uint32_t aIndex, const std::pair<wxString, wxString>& aStart,
266 const std::pair<wxString, wxString>& aEnd, uint32_t aSym ) :
267 ODB_FEATURE( aIndex ),
268 m_start( aStart ),
269 m_end( aEnd ),
270 m_symIndex( aSym )
271 {}
272
273 inline virtual FEATURE_TYPE GetFeatureType() override { return FEATURE_TYPE::LINE; }
274
275protected:
276 virtual void WriteRecordContent( std::ostream& ost, const ODB_FORMAT& aFormat ) override;
277
278private:
279 std::pair<wxString, wxString> m_start;
280 std::pair<wxString, wxString> m_end;
281 uint32_t m_symIndex;
282};
283
284
285class ODB_ARC : public ODB_FEATURE
286{
287public:
288 inline virtual FEATURE_TYPE GetFeatureType() override { return FEATURE_TYPE::ARC; }
289
290
291 ODB_ARC( uint32_t aIndex, const std::pair<wxString, wxString>& aStart,
292 const std::pair<wxString, wxString>& aEnd,
293 const std::pair<wxString, wxString>& aCenter, uint32_t aSym,
294 ODB_DIRECTION aDirection ) :
295 ODB_FEATURE( aIndex ),
296 m_start( aStart ),
297 m_end( aEnd ),
298 m_center( aCenter ),
299 m_symIndex( aSym ),
300 m_direction( aDirection )
301 {}
302
303protected:
304 virtual void WriteRecordContent( std::ostream& ost, const ODB_FORMAT& aFormat ) override;
305
306private:
307 std::pair<wxString, wxString> m_start;
308 std::pair<wxString, wxString> m_end;
309 std::pair<wxString, wxString> m_center;
310 uint32_t m_symIndex;
312};
313
314class ODB_PAD : public ODB_FEATURE
315{
316public:
317 ODB_PAD( uint32_t aIndex, const std::pair<wxString, wxString>& aCenter, uint32_t aSym, EDA_ANGLE aAngle = ANGLE_0,
318 double aResize = 1.0 ) :
319 ODB_FEATURE( aIndex ),
320 m_center( aCenter ),
321 m_symIndex( aSym ),
322 m_angle( aAngle ),
323 m_resize( aResize )
324 {
325 }
326
327 inline virtual FEATURE_TYPE GetFeatureType() override { return FEATURE_TYPE::PAD; }
328
329protected:
330 virtual void WriteRecordContent( std::ostream& ost, const ODB_FORMAT& aFormat ) override;
331
332private:
333 std::pair<wxString, wxString> m_center;
334 uint32_t m_symIndex;
336 double m_resize;
337};
338
339class ODB_SURFACE_DATA;
341{
342public:
343 ODB_SURFACE( uint32_t aIndex, const SHAPE_POLY_SET::POLYGON& aPolygon,
344 FILL_T aFillType = FILL_T::FILLED_SHAPE );
345
346 virtual ~ODB_SURFACE() = default;
347
348 inline virtual FEATURE_TYPE GetFeatureType() override { return FEATURE_TYPE::SURFACE; }
349
350 std::unique_ptr<ODB_SURFACE_DATA> m_surfaces;
351
352protected:
353 virtual void WriteRecordContent( std::ostream& ost, const ODB_FORMAT& aFormat ) override;
354};
355
356
358{
359public:
360 ODB_SURFACE_DATA( const SHAPE_POLY_SET::POLYGON& aPolygon );
361
363 {
364 enum class LINE_TYPE
365 {
368 };
369
370 SURFACE_LINE() = default;
371
372 SURFACE_LINE( const VECTOR2I& aEnd ) :
373 m_end( aEnd )
374 {}
375
376 SURFACE_LINE( const VECTOR2I& aEnd, const VECTOR2I& aCenter, ODB_DIRECTION aDirection ) :
377 m_end( aEnd ),
378 m_type( LINE_TYPE::ARC ),
379 m_center( aCenter ),
380 m_direction( aDirection )
381 {}
382
385
388 };
389
390 void AddPolygonHoles( const SHAPE_POLY_SET::POLYGON& aPolygon );
391 void WriteData( std::ostream& ost, const ODB_FORMAT& aFormat ) const;
392
393 std::vector<std::vector<SURFACE_LINE>> m_polygons;
394
395private:
396 void AddContour( const SHAPE_LINE_CHAIN& aChain, bool aHole );
397};
int index
ATTR_MANAGER()=default
ATTR_RECORD_WRITER()=default
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
void AddPadShape(const PAD &aPad, PCB_LAYER_ID aLayer)
uint32_t AddRoundRectDonutSymbol(const wxString &aOuterWidth, const wxString &aOuterHeight, const wxString &aLineWidth, const wxString &aRadius)
std::map< wxString, uint32_t > m_circleSymMap
uint32_t m_symIndex
uint32_t AddRectSymbol(const wxString &aWidth, const wxString &aHeight)
void AddRoutSlot(const PAD &aPad, int aChain)
void AddPad(PCB_LAYER_ID aLayer, PAD *pad)
std::map< wxString, uint32_t > m_chamRectSymMap
size_t FeatureCount() const
Definition odb_feature.h:92
void addPostMachiningAttributes(ODB_FEATURE &aFeature, const DRILL_OPERATION &aOperation)
void AddVia(const PCB_VIA *aVia, PCB_LAYER_ID aLayer)
void AddDimension(PCB_LAYER_ID aLayer, PCB_DIMENSION_BASE *dimension)
std::map< wxString, uint32_t > m_rectSymMap
void tagRoutFeatures(size_t aFirst, int aChain, bool aPlated)
PCB_IO_ODBPP * GetODBPlugin()
void AddShape(PCB_LAYER_ID aLayer, PCB_SHAPE *shape)
void AddFeatureLine(const VECTOR2I &aStart, const VECTOR2I &aEnd, uint64_t aWidth)
PCB_IO_ODBPP * m_plugin
void AddViaProtection(const PCB_VIA *aVia, bool drill, PCB_LAYER_ID aLayer)
FEATURES_MANAGER(BOARD *aBoard, PCB_IO_ODBPP *aPlugin, const wxString &aLayerName, ODB_LAYER_ROLE aRole, std::optional< ODB_AUX_LAYER_TYPE > aAuxType, std::optional< DRILL_SPAN > aDrillSpan=std::nullopt)
Definition odb_feature.h:58
void AddFeatureArc(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, uint64_t aWidth, ODB_DIRECTION aDirection)
uint32_t GetSymbolIndex(std::map< wxString, uint32_t > &aSymMap, const wxString &aKey)
std::map< uint32_t, wxString > m_allSymMap
bool AddPolygon(const SHAPE_POLY_SET::POLYGON &aPolygon, FILL_T aFillType, int aWidth, LINE_STYLE aDashType)
void GenerateFeatureFile(std::ostream &ost) const
void addViaDrillAttributes(ODB_FEATURE &aFeature, const PCB_VIA *aVia)
std::map< wxString, uint32_t > m_roundRectDonutSymMap
std::map< wxString, uint32_t > m_ovalSymMap
ODB_LAYER_ROLE m_role
std::map< wxString, uint32_t > m_roundDonutSymMap
void AddTrack(PCB_LAYER_ID aLayer, PCB_TRACK *track)
void AddZone(PCB_LAYER_ID aLayer, ZONE *zone)
std::map< wxString, uint32_t > m_roundRectSymMap
bool AddViaDrillHole(const PCB_VIA *aVia, PCB_LAYER_ID aLayer)
void AddText(PCB_LAYER_ID aLayer, BOARD_ITEM *item, RESOLUTION_CONTEXT aContext)
std::optional< DRILL_SPAN > m_drillSpan
std::optional< ODB_AUX_LAYER_TYPE > m_auxType
void InitFeatureList(PCB_LAYER_ID aLayer, const std::vector< BOARD_ITEM * > &aItems)
uint32_t AddRoundRectSymbol(const wxString &aWidth, const wxString &aHeight, const wxString &aRadius)
wxString m_layerName
void AddPadCircle(const VECTOR2I &aCenter, uint64_t aDiameter)
void forEachNewFeature(size_t aFirst, F &&aFunc)
void AddRoutContour(const SHAPE_LINE_CHAIN &aContour, int aChain, bool aPlated)
bool AddFeatureSurface(const SHAPE_POLY_SET::POLYGON &aPolygon, FILL_T aFillType=FILL_T::FILLED_SHAPE)
uint32_t AddOvalSymbol(const wxString &aWidth, const wxString &aHeight)
void GenerateProfileFeatures(std::ostream &ost) const
std::list< std::unique_ptr< ODB_FEATURE > > m_featuresList
void AddFeature(Args &&... args)
bool AddPolygonCutouts(const SHAPE_POLY_SET::POLYGON &aPolygon)
uint32_t AddCircleSymbol(const wxString &aDiameter)
uint32_t AddChamferRectSymbol(const wxString &aWidth, const wxString &aHeight, const wxString &aRadius, int aPositions)
std::map< wxString, uint32_t > m_padSymMap
uint32_t AddRoundDonutSymbol(const wxString &aOuterDim, const wxString &aInnerDim)
bool AddContour(const SHAPE_POLY_SET &aPolySet, int aOutline=0, FILL_T aFillType=FILL_T::FILLED_SHAPE)
std::pair< wxString, wxString > m_end
std::pair< wxString, wxString > m_start
ODB_ARC(uint32_t aIndex, const std::pair< wxString, wxString > &aStart, const std::pair< wxString, wxString > &aEnd, const std::pair< wxString, wxString > &aCenter, uint32_t aSym, ODB_DIRECTION aDirection)
uint32_t m_symIndex
virtual FEATURE_TYPE GetFeatureType() override
virtual void WriteRecordContent(std::ostream &ost, const ODB_FORMAT &aFormat) override
ODB_DIRECTION m_direction
std::pair< wxString, wxString > m_center
virtual ~ODB_FEATURE()=default
virtual FEATURE_TYPE GetFeatureType()=0
const uint32_t m_index
virtual void WriteRecordContent(std::ostream &ost, const ODB_FORMAT &aFormat)=0
virtual void WriteFeatures(std::ostream &ost, const ODB_FORMAT &aFormat)
ODB_FEATURE(uint32_t aIndex)
virtual void WriteRecordContent(std::ostream &ost, const ODB_FORMAT &aFormat) override
ODB_LINE(uint32_t aIndex, const std::pair< wxString, wxString > &aStart, const std::pair< wxString, wxString > &aEnd, uint32_t aSym)
virtual FEATURE_TYPE GetFeatureType() override
std::pair< wxString, wxString > m_start
std::pair< wxString, wxString > m_end
uint32_t m_symIndex
ODB_PAD(uint32_t aIndex, const std::pair< wxString, wxString > &aCenter, uint32_t aSym, EDA_ANGLE aAngle=ANGLE_0, double aResize=1.0)
uint32_t m_symIndex
virtual FEATURE_TYPE GetFeatureType() override
double m_resize
virtual void WriteRecordContent(std::ostream &ost, const ODB_FORMAT &aFormat) override
EDA_ANGLE m_angle
std::pair< wxString, wxString > m_center
std::vector< std::vector< SURFACE_LINE > > m_polygons
void AddContour(const SHAPE_LINE_CHAIN &aChain, bool aHole)
void WriteData(std::ostream &ost, const ODB_FORMAT &aFormat) const
ODB_SURFACE_DATA(const SHAPE_POLY_SET::POLYGON &aPolygon)
void AddPolygonHoles(const SHAPE_POLY_SET::POLYGON &aPolygon)
std::unique_ptr< ODB_SURFACE_DATA > m_surfaces
virtual FEATURE_TYPE GetFeatureType() override
virtual ~ODB_SURFACE()=default
virtual void WriteRecordContent(std::ostream &ost, const ODB_FORMAT &aFormat) override
ODB_SURFACE(uint32_t aIndex, const SHAPE_POLY_SET::POLYGON &aPolygon, FILL_T aFillType=FILL_T::FILLED_SHAPE)
Definition pad.h:61
Abstract dimension API.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
std::vector< SHAPE_LINE_CHAIN > POLYGON
represents a single polygon outline with holes.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
RESOLUTION_CONTEXT
Definition common.h:89
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:448
FILL_T
Definition eda_fill.h:29
@ FILLED_SHAPE
Fill with object color.
Definition eda_fill.h:31
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ UNDEFINED_LAYER
Definition layer_ids.h:57
#define F(x, y, z)
Definition md5_hash.cpp:15
#define ODB_DIM_R
Definition odb_defines.h:30
#define ODB_DIM_C
Definition odb_defines.h:31
#define ODB_DIM_X
Definition odb_defines.h:29
ODB_DIRECTION
Definition odb_feature.h:37
ODB_LAYER_ROLE
Definition odb_util.h:156
LINE_STYLE
Dashed line types.
One machining action, which is also one NC hit and one tool assignment.
SURFACE_LINE(const VECTOR2I &aEnd)
SURFACE_LINE(const VECTOR2I &aEnd, const VECTOR2I &aCenter, ODB_DIRECTION aDirection)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708