KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_io_pads_binary.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 (C) 2026 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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "pcb_io_pads_binary.h"
25#include "pads_binary_parser.h"
26#include "pads_layer_mapper.h"
27
28#include <algorithm>
29#include <cmath>
30#include <functional>
31#include <set>
32
33#include <board.h>
34#include <pcb_track.h>
35#include <pcb_text.h>
36#include <footprint.h>
37#include <zone.h>
38
40#include <io/pads/pads_common.h>
41
42#include <netinfo.h>
43#include <wx/log.h>
44#include <wx/file.h>
45#include <wx/filename.h>
46#include <pad.h>
47#include <pcb_shape.h>
49#include <netclass.h>
50#include <geometry/eda_angle.h>
51#include <string_utils.h>
52#include <progress_reporter.h>
53#include <reporter.h>
54#include <locale_io.h>
55#include <advanced_config.h>
56#include <geometry/shape_arc.h>
57
58
60{
63 std::placeholders::_1 ) );
64}
65
66
68
69
71{
72 IO_FILE_DESC desc;
73 desc.m_FileExtensions.emplace_back( "pcb" );
74 desc.m_Description = "PADS Binary";
75 return desc;
76}
77
78
80{
81 return IO_FILE_DESC( "PADS Binary Library", { "pcb" } );
82}
83
84
85long long PCB_IO_PADS_BINARY::GetLibraryTimestamp( const wxString& aLibraryPath ) const
86{
87 return 0;
88}
89
90
91bool PCB_IO_PADS_BINARY::CanReadBoard( const wxString& aFileName ) const
92{
93 if( !PCB_IO::CanReadBoard( aFileName ) )
94 return false;
95
97}
98
99
100BOARD* PCB_IO_PADS_BINARY::LoadBoard( const wxString& aFileName, BOARD* aAppendToMe,
101 const std::map<std::string, UTF8>* aProperties,
102 PROJECT* aProject )
103{
104 LOCALE_IO setlocale;
105
106 std::unique_ptr<BOARD> board( aAppendToMe ? aAppendToMe : new BOARD() );
107
108 if( m_reporter )
109 m_reporter->Report( _( "Starting PADS binary PCB import" ), RPT_SEVERITY_INFO );
110
112 m_progressReporter->SetNumPhases( 3 );
113
115
116 try
117 {
118 parser.Parse( aFileName );
119 }
120 catch( const std::exception& e )
121 {
122 THROW_IO_ERROR( wxString::Format( "Error parsing PADS binary file: %s", e.what() ) );
123 }
124
125 m_loadBoard = board.get();
126 m_parser = &parser;
127
128 try
129 {
131 m_progressReporter->BeginPhase( 1 );
132
134 loadNets();
135
137 m_progressReporter->BeginPhase( 2 );
138
142 loadTexts();
143 loadZones();
144
146 }
147 catch( ... )
148 {
150 throw;
151 }
152
154 return board.release();
155}
156
157
159{
160 m_layerMapper.SetCopperLayerCount( m_parser->GetParameters().layer_count );
161
162 std::vector<PADS_IO::LAYER_INFO> padsLayerInfos = m_parser->GetLayerInfos();
163
164 auto convertLayerType = []( PADS_IO::PADS_LAYER_FUNCTION func ) -> PADS_LAYER_TYPE {
165 switch( func )
166 {
183 default:
185 }
186 };
187
188 for( const auto& padsInfo : padsLayerInfos )
189 {
191 info.padsLayerNum = padsInfo.number;
192 info.name = padsInfo.name;
193
194 if( padsInfo.layer_type != PADS_IO::PADS_LAYER_FUNCTION::UNKNOWN )
195 {
196 info.type = convertLayerType( padsInfo.layer_type );
197
199 {
200 if( padsInfo.number == 1 )
202 else if( padsInfo.number == m_parser->GetParameters().layer_count )
204 }
205 }
206 else
207 {
208 info.type = m_layerMapper.GetLayerType( padsInfo.number );
209 }
210
211 info.required = padsInfo.required;
212 m_layerInfos.push_back( info );
213 }
214
215 std::vector<INPUT_LAYER_DESC> inputDescs =
216 m_layerMapper.BuildInputLayerDescriptions( m_layerInfos );
217
219 m_layerMap = m_layer_mapping_handler( inputDescs );
220
221 int copperLayerCount = m_parser->GetParameters().layer_count;
222
223 if( copperLayerCount < 1 )
224 copperLayerCount = 2;
225
226 m_loadBoard->SetCopperLayerCount( copperLayerCount );
227
228 // Binary files always use BASIC units
229 m_unitConverter.SetBasicUnitsMode( true );
231
232 m_originX = m_parser->GetParameters().origin.x;
233 m_originY = m_parser->GetParameters().origin.y;
234
235 // Fall back to board outline center only when the parser found no DFT origin.
236 // The DFT origin produces exact coordinate matches; overriding it shifts all parts.
237 if( m_originX == 0.0 && m_originY == 0.0 )
238 {
239 const auto& boardOutlines = m_parser->GetBoardOutlines();
240
241 if( !boardOutlines.empty() )
242 {
243 double minX = std::numeric_limits<double>::max();
244 double maxX = std::numeric_limits<double>::lowest();
245 double minY = std::numeric_limits<double>::max();
246 double maxY = std::numeric_limits<double>::lowest();
247
248 for( const auto& outline : boardOutlines )
249 {
250 for( const auto& pt : outline.points )
251 {
252 minX = std::min( minX, pt.x );
253 maxX = std::max( maxX, pt.x );
254 minY = std::min( minY, pt.y );
255 maxY = std::max( maxY, pt.y );
256 }
257 }
258
259 if( minX < maxX && minY < maxY )
260 {
261 m_originX = ( minX + maxX ) / 2.0;
262 m_originY = ( minY + maxY ) / 2.0;
263 }
264 }
265 }
266}
267
268
270{
271 const auto& nets = m_parser->GetNets();
272
273 for( const auto& padsNet : nets )
274 ensureNet( padsNet.name );
275}
276
277
279{
280 const auto& decals = m_parser->GetPartDecals();
281 const auto& parts = m_parser->GetParts();
282
283 for( const auto& padsPart : parts )
284 {
285 FOOTPRINT* footprint = new FOOTPRINT( m_loadBoard );
286 footprint->SetReference( padsPart.name );
287
288 KIID symbolUuid = PADS_COMMON::GenerateDeterministicUuid( padsPart.name );
290 path.push_back( symbolUuid );
291 footprint->SetPath( path );
292
293 std::string decalName = padsPart.decal;
294
295 LIB_ID fpid;
296
297 if( !decalName.empty() )
298 fpid.SetLibItemName( wxString::FromUTF8( decalName ) );
299 else
300 fpid.SetLibItemName( wxString::FromUTF8( padsPart.name ) );
301
302 footprint->SetFPID( fpid );
303 footprint->SetValue( padsPart.decal );
304
305 footprint->SetPosition( VECTOR2I( scaleCoord( padsPart.location.x, true ),
306 scaleCoord( padsPart.location.y, false ) ) );
307 footprint->SetOrientation( EDA_ANGLE( padsPart.rotation, DEGREES_T ) );
308 footprint->SetLayer( F_Cu );
309
310 m_loadBoard->Add( footprint );
311
312 if( padsPart.bottom_layer )
313 footprint->Flip( footprint->GetPosition(), FLIP_DIRECTION::LEFT_RIGHT );
314 }
315}
316
317
319{
320 for( const PADS_IO::POLYLINE& polyline : m_parser->GetBoardOutlines() )
321 {
322 const auto& pts = polyline.points;
323
324 if( pts.size() < 2 )
325 continue;
326
327 for( size_t i = 0; i < pts.size() - 1; ++i )
328 {
329 const PADS_IO::ARC_POINT& p1 = pts[i];
330 const PADS_IO::ARC_POINT& p2 = pts[i + 1];
331
332 if( std::abs( p1.x - p2.x ) < 0.001 && std::abs( p1.y - p2.y ) < 0.001 )
333 continue;
334
335 PCB_SHAPE* shape = new PCB_SHAPE( m_loadBoard );
336 shape->SetShape( SHAPE_T::SEGMENT );
337 shape->SetStart( VECTOR2I( scaleCoord( p1.x, true ),
338 scaleCoord( p1.y, false ) ) );
339 shape->SetEnd( VECTOR2I( scaleCoord( p2.x, true ),
340 scaleCoord( p2.y, false ) ) );
341 shape->SetWidth( scaleSize( polyline.width ) );
342 shape->SetLayer( Edge_Cuts );
343 m_loadBoard->Add( shape );
344 }
345
346 if( polyline.closed && pts.size() > 2 )
347 {
348 const PADS_IO::ARC_POINT& pLast = pts.back();
349 const PADS_IO::ARC_POINT& pFirst = pts.front();
350
351 bool needsClosing = ( std::abs( pLast.x - pFirst.x ) > 0.001
352 || std::abs( pLast.y - pFirst.y ) > 0.001 );
353
354 if( needsClosing )
355 {
356 PCB_SHAPE* shape = new PCB_SHAPE( m_loadBoard );
357 shape->SetShape( SHAPE_T::SEGMENT );
358 shape->SetStart( VECTOR2I( scaleCoord( pLast.x, true ),
359 scaleCoord( pLast.y, false ) ) );
360 shape->SetEnd( VECTOR2I( scaleCoord( pFirst.x, true ),
361 scaleCoord( pFirst.y, false ) ) );
362 shape->SetWidth( scaleSize( polyline.width ) );
363 shape->SetLayer( Edge_Cuts );
364 m_loadBoard->Add( shape );
365 }
366 }
367 }
368}
369
370
372{
373 const auto& routes = m_parser->GetRoutes();
374 std::set<std::pair<int, int>> placedThroughVias;
375
376 for( const auto& route : routes )
377 {
378 NETINFO_ITEM* net = nullptr;
379
380 if( !route.net_name.empty() )
381 {
382 net = m_loadBoard->FindNet(
383 PADS_COMMON::ConvertInvertedNetName( route.net_name ) );
384
385 if( !net )
386 continue;
387 }
388
389 for( const auto& track_def : route.tracks )
390 {
391 if( track_def.points.size() < 2 )
392 continue;
393
394 PCB_LAYER_ID track_layer = getMappedLayer( track_def.layer );
395
396 // Binary routes with layer 0 default to F_Cu since the binary
397 // format's layer field mapping is not yet fully decoded.
398 if( !IsCopperLayer( track_layer ) )
399 {
400 if( route.net_name.empty() && track_def.layer == 0 )
401 {
402 track_layer = F_Cu;
403 }
404 else
405 {
406 if( m_reporter )
407 {
408 m_reporter->Report( wxString::Format(
409 _( "Skipping track on non-copper layer %d" ), track_def.layer ),
411 }
412
413 continue;
414 }
415 }
416
417 int track_width = scaleSize( track_def.width );
418
419 if( track_width <= 0 )
420 track_width = scaleSize( 8.0 );
421
422 for( size_t i = 0; i < track_def.points.size() - 1; ++i )
423 {
424 const PADS_IO::ARC_POINT& p1 = track_def.points[i];
425 const PADS_IO::ARC_POINT& p2 = track_def.points[i + 1];
426
427 VECTOR2I start( scaleCoord( p1.x, true ), scaleCoord( p1.y, false ) );
428 VECTOR2I end( scaleCoord( p2.x, true ), scaleCoord( p2.y, false ) );
429
430 if( ( start - end ).EuclideanNorm() < 1000 )
431 continue;
432
433 if( p2.is_arc )
434 {
435 VECTOR2I center( scaleCoord( p2.arc.cx, true ),
436 scaleCoord( p2.arc.cy, false ) );
437
438 bool clockwise = ( p2.arc.delta_angle < 0 );
439
440 SHAPE_ARC shapeArc;
441 shapeArc.ConstructFromStartEndCenter( start, end, center, clockwise,
442 track_width );
443
444 PCB_ARC* arc = new PCB_ARC( m_loadBoard, &shapeArc );
445
446 if( net )
447 arc->SetNet( net );
448
449 arc->SetWidth( track_width );
450 arc->SetLayer( track_layer );
451 m_loadBoard->Add( arc );
452 }
453 else
454 {
455 PCB_TRACK* track = new PCB_TRACK( m_loadBoard );
456
457 if( net )
458 track->SetNet( net );
459
460 track->SetWidth( track_width );
461 track->SetLayer( track_layer );
462 track->SetStart( start );
463 track->SetEnd( end );
464 m_loadBoard->Add( track );
465 }
466 }
467 }
468
469 for( const auto& via_def : route.vias )
470 {
471 VECTOR2I pos( scaleCoord( via_def.location.x, true ),
472 scaleCoord( via_def.location.y, false ) );
473
474 if( placedThroughVias.count( std::make_pair( pos.x, pos.y ) ) )
475 continue;
476
477 placedThroughVias.insert( std::make_pair( pos.x, pos.y ) );
478
479 PCB_VIA* via = new PCB_VIA( m_loadBoard );
480
481 if( net )
482 via->SetNet( net );
483
484 via->SetPosition( pos );
485 via->SetWidth( scaleSize( 20.0 ) );
486 via->SetDrill( scaleSize( 10.0 ) );
487 via->SetLayerPair( F_Cu, B_Cu );
488 via->SetViaType( VIATYPE::THROUGH );
489 m_loadBoard->Add( via );
490 }
491 }
492}
493
494
496{
497 const auto& texts = m_parser->GetTexts();
498
499 for( const auto& pads_text : texts )
500 {
501 PCB_LAYER_ID textLayer = getMappedLayer( pads_text.layer );
502
503 if( textLayer == UNDEFINED_LAYER )
504 {
505 if( m_reporter )
506 {
507 m_reporter->Report( wxString::Format(
508 _( "Text on unmapped layer %d assigned to Comments layer" ),
509 pads_text.layer ), RPT_SEVERITY_WARNING );
510 }
511
512 textLayer = Cmts_User;
513 }
514
516 text->SetText( pads_text.content );
517
518 int scaledSize = scaleSize( pads_text.height );
519 int charHeight =
520 static_cast<int>( scaledSize * ADVANCED_CFG::GetCfg().m_PadsPcbTextHeightScale );
521 int charWidth =
522 static_cast<int>( scaledSize * ADVANCED_CFG::GetCfg().m_PadsPcbTextWidthScale );
523 text->SetTextSize( VECTOR2I( charWidth, charHeight ) );
524
525 if( pads_text.width > 0 )
526 text->SetTextThickness( scaleSize( pads_text.width ) );
527
528 EDA_ANGLE textAngle( pads_text.rotation, DEGREES_T );
529 text->SetTextAngle( textAngle );
530
531 VECTOR2I pos( scaleCoord( pads_text.location.x, true ),
532 scaleCoord( pads_text.location.y, false ) );
533 VECTOR2I textShift( -ADVANCED_CFG::GetCfg().m_PadsTextAnchorOffsetNm, 0 );
534 RotatePoint( textShift, textAngle );
535 text->SetPosition( pos + textShift );
536
537 if( pads_text.hjust == "LEFT" )
538 text->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
539 else if( pads_text.hjust == "RIGHT" )
540 text->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
541 else
542 text->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
543
544 if( pads_text.vjust == "UP" )
545 text->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
546 else if( pads_text.vjust == "DOWN" )
547 text->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
548 else
549 text->SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
550
551 text->SetKeepUpright( false );
552 text->SetLayer( textLayer );
553 m_loadBoard->Add( text );
554 }
555}
556
557
559{
560 const auto& pours = m_parser->GetPours();
561 const auto& params = m_parser->GetParameters();
562
563 int maxPriority = 0;
564
565 for( const auto& pour_def : pours )
566 {
567 if( pour_def.priority > maxPriority )
568 maxPriority = pour_def.priority;
569 }
570
571 for( const auto& pour_def : pours )
572 {
573 PCB_LAYER_ID pourLayer = getMappedLayer( pour_def.layer );
574
575 if( pourLayer == UNDEFINED_LAYER )
576 {
577 if( m_reporter )
578 {
579 m_reporter->Report( wxString::Format(
580 _( "Skipping pour on unmapped layer %d" ), pour_def.layer ),
582 }
583
584 continue;
585 }
586
587 ZONE* zone = new ZONE( m_loadBoard );
588 zone->SetLayer( pourLayer );
589
590 zone->Outline()->NewOutline();
591
592 for( const auto& pt : pour_def.points )
593 {
594 zone->Outline()->Append( scaleCoord( pt.x, true ), scaleCoord( pt.y, false ) );
595 }
596
597 if( zone->GetNumCorners() == 0 )
598 {
599 delete zone;
600 continue;
601 }
602
603 if( pour_def.is_cutout )
604 {
605 zone->SetIsRuleArea( true );
606 zone->SetDoNotAllowZoneFills( true );
607 zone->SetDoNotAllowTracks( false );
608 zone->SetDoNotAllowVias( false );
609 zone->SetDoNotAllowPads( false );
610 zone->SetDoNotAllowFootprints( false );
611 zone->SetZoneName( wxString::Format( wxT( "Cutout_%s" ), pour_def.owner_pour ) );
612 }
613 else
614 {
615 NETINFO_ITEM* net = m_loadBoard->FindNet(
616 PADS_COMMON::ConvertInvertedNetName( pour_def.net_name ) );
617
618 if( net )
619 zone->SetNet( net );
620
621 int kicadPriority = maxPriority - pour_def.priority + 1;
622 zone->SetAssignedPriority( kicadPriority );
623 zone->SetMinThickness( scaleSize( pour_def.width ) );
624
625 zone->SetThermalReliefGap( scaleSize( params.thermal_min_clearance ) );
626 zone->SetThermalReliefSpokeWidth( scaleSize( params.thermal_line_width ) );
627
629 }
630
631 m_loadBoard->Add( zone );
632 }
633}
634
635
637{
638 if( !m_reporter )
639 return;
640
641 size_t trackCount = 0;
642 size_t viaCount = 0;
643
644 for( PCB_TRACK* track : m_loadBoard->Tracks() )
645 {
646 if( track->Type() == PCB_VIA_T )
647 viaCount++;
648 else
649 trackCount++;
650 }
651
652 m_reporter->Report( wxString::Format( _( "Imported %zu footprints, %d nets, %zu tracks,"
653 " %zu vias, %zu zones" ),
654 m_loadBoard->Footprints().size(),
655 m_loadBoard->GetNetCount(),
656 trackCount, viaCount,
657 m_loadBoard->Zones().size() ),
659}
660
661
662std::map<wxString, PCB_LAYER_ID> PCB_IO_PADS_BINARY::DefaultLayerMappingCallback(
663 const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
664{
665 std::map<wxString, PCB_LAYER_ID> layerMap;
666
667 for( const INPUT_LAYER_DESC& layer : aInputLayerDescriptionVector )
668 layerMap[layer.Name] = layer.AutoMapLayer;
669
670 return layerMap;
671}
672
673
674int PCB_IO_PADS_BINARY::scaleSize( double aVal ) const
675{
676 return static_cast<int>( m_unitConverter.ToNanometersSize( aVal ) );
677}
678
679
680int PCB_IO_PADS_BINARY::scaleCoord( double aVal, bool aIsX ) const
681{
682 double origin = aIsX ? m_originX : m_originY;
683
684 long long originNm = static_cast<long long>( std::round( origin * m_scaleFactor ) );
685 long long valNm = static_cast<long long>( std::round( aVal * m_scaleFactor ) );
686
687 if( aIsX )
688 return static_cast<int>( valNm - originNm );
689 else
690 return static_cast<int>( originNm - valNm );
691}
692
693
695{
696 for( const auto& info : m_layerInfos )
697 {
698 if( info.padsLayerNum == aPadsLayer )
699 {
700 auto it = m_layerMap.find( wxString::FromUTF8( info.name ) );
701
702 if( it != m_layerMap.end() && it->second != UNDEFINED_LAYER )
703 return it->second;
704
705 return m_layerMapper.GetAutoMapLayer( aPadsLayer, info.type );
706 }
707 }
708
709 return m_layerMapper.GetAutoMapLayer( aPadsLayer );
710}
711
712
713void PCB_IO_PADS_BINARY::ensureNet( const std::string& aNetName )
714{
715 if( aNetName.empty() )
716 return;
717
718 wxString wxName = PADS_COMMON::ConvertInvertedNetName( aNetName );
719
720 if( m_loadBoard->FindNet( wxName ) == nullptr )
721 {
722 NETINFO_ITEM* net = new NETINFO_ITEM(
723 m_loadBoard, wxName,
724 static_cast<int>( m_loadBoard->GetNetCount() ) + 1 );
725 m_loadBoard->Add( net );
726 }
727}
728
729
731{
732 m_loadBoard = nullptr;
733 m_parser = nullptr;
736 m_layerInfos.clear();
737 m_scaleFactor = 0.0;
738 m_originX = 0.0;
739 m_originY = 0.0;
740 m_pinToNetMap.clear();
741}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:285
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:178
void SetShape(SHAPE_T aShape)
Definition eda_shape.h:168
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:220
void SetWidth(int aWidth)
void SetPosition(const VECTOR2I &aPos) override
void SetFPID(const LIB_ID &aFPID)
Definition footprint.h:352
void SetOrientation(const EDA_ANGLE &aNewAngle)
void SetPath(const KIID_PATH &aPath)
Definition footprint.h:375
void SetReference(const wxString &aReference)
Definition footprint.h:757
void SetValue(const wxString &aValue)
Definition footprint.h:778
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
VECTOR2I GetPosition() const override
Definition footprint.h:327
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
Definition io_base.h:237
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
Definition io_base.h:240
Definition kiid.h:49
virtual void RegisterCallback(LAYER_MAPPING_HANDLER aLayerMappingHandler)
Register a different handler to be called when mapping of input layers to KiCad layers occurs.
LAYER_MAPPING_HANDLER m_layer_mapping_handler
Callback to get layer mapping.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:111
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
Handle the data for a net.
Definition netinfo.h:54
Parser for PADS binary PCB file format (.pcb).
static bool IsBinaryPadsFile(const wxString &aFileName)
Check if a file appears to be a PADS binary PCB file.
void Parse(const wxString &aFileName)
Maps PADS layer numbers and names to KiCad layer IDs.
Converts PADS file format units to KiCad internal units (nanometers).
static constexpr double BASIC_TO_NM
long long GetLibraryTimestamp(const wxString &aLibraryPath) const override
Generate a timestamp representing all the files in the library (including the library directory).
const IO_FILE_DESC GetBoardFileDesc() const override
Returns board file description for the PCB_IO.
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties, PROJECT *aProject) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
bool CanReadBoard(const wxString &aFileName) const override
Checks if this PCB_IO can read the specified board file.
~PCB_IO_PADS_BINARY() override
int scaleSize(double aVal) const
const IO_FILE_DESC GetLibraryDesc() const override
Get the descriptor for the library container that this IO plugin operates on.
const PADS_IO::BINARY_PARSER * m_parser
PCB_LAYER_ID getMappedLayer(int aPadsLayer) const
PADS_UNIT_CONVERTER m_unitConverter
void ensureNet(const std::string &aNetName)
int scaleCoord(double aVal, bool aIsX) const
std::vector< PADS_LAYER_INFO > m_layerInfos
PADS_LAYER_MAPPER m_layerMapper
std::map< wxString, PCB_LAYER_ID > m_layerMap
std::map< std::string, std::string > m_pinToNetMap
std::map< wxString, PCB_LAYER_ID > DefaultLayerMappingCallback(const std::vector< INPUT_LAYER_DESC > &aInputLayerDescriptionVector)
virtual bool CanReadBoard(const wxString &aFileName) const
Checks if this PCB_IO can read the specified board file.
Definition pcb_io.cpp:42
PCB_IO(const wxString &aName)
Definition pcb_io.h:337
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetEnd(const VECTOR2I &aEnd)
Definition pcb_track.h:150
void SetStart(const VECTOR2I &aStart)
Definition pcb_track.h:153
virtual void SetWidth(int aWidth)
Definition pcb_track.h:147
Container for project specific data.
Definition project.h:65
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
Handle a list of polygons defining a copper zone.
Definition zone.h:73
void SetDoNotAllowPads(bool aEnable)
Definition zone.h:738
void SetMinThickness(int aMinThickness)
Definition zone.h:307
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
Definition zone.h:237
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition zone.cpp:550
SHAPE_POLY_SET * Outline()
Definition zone.h:340
void SetIsRuleArea(bool aEnable)
Definition zone.h:720
void SetDoNotAllowTracks(bool aEnable)
Definition zone.h:737
void SetDoNotAllowVias(bool aEnable)
Definition zone.h:736
void SetThermalReliefGap(int aThermalReliefGap)
Definition zone.h:226
void SetDoNotAllowFootprints(bool aEnable)
Definition zone.h:739
void SetDoNotAllowZoneFills(bool aEnable)
Definition zone.h:735
void SetAssignedPriority(unsigned aPriority)
Definition zone.h:120
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition zone.h:304
void SetZoneName(const wxString &aName)
Definition zone.h:164
int GetNumCorners(void) const
Access to m_Poly parameters.
Definition zone.h:524
#define _(s)
@ DEGREES_T
Definition eda_angle.h:31
@ SEGMENT
Definition eda_shape.h:45
double m_PadsPcbTextWidthScale
PADS text width scale factor for PCB imports.
double m_PadsPcbTextHeightScale
PADS text height scale factor for PCB imports.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition layer_ids.h:677
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ Edge_Cuts
Definition layer_ids.h:112
@ Cmts_User
Definition layer_ids.h:108
@ B_Cu
Definition layer_ids.h:65
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:64
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Definition mirror.h:28
wxString ConvertInvertedNetName(const std::string &aNetName)
Convert a PADS net name to KiCad format, handling inverted signal notation.
KIID GenerateDeterministicUuid(const std::string &aIdentifier)
Generate a deterministic KIID from a PADS component identifier.
PADS_LAYER_FUNCTION
Layer types from PADS LAYER_TYPE field.
@ ASSEMBLY
Assembly drawing.
@ ROUTING
Copper routing layer.
@ PASTE_MASK
Solder paste mask.
@ MIXED
Mixed signal/plane.
@ DOCUMENTATION
Documentation layer.
@ SILK_SCREEN
Silkscreen/legend.
@ PLANE
Power/ground plane.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
Common utilities and types for parsing PADS file formats.
PADS_LAYER_TYPE
PADS layer types.
@ THROUGH
Definition pcb_track.h:68
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_INFO
Describes an imported layer and how it could be mapped to KiCad Layers.
Container that describes file type info.
Definition io_base.h:43
wxString m_Description
Description shown in the file picker dialog.
Definition io_base.h:44
std::vector< std::string > m_FileExtensions
Filter used for file pickers if m_IsFile is true.
Definition io_base.h:47
A point that may be either a line endpoint or an arc segment.
Definition pads_parser.h:72
ARC arc
Arc parameters (only valid when is_arc is true)
Definition pads_parser.h:76
bool is_arc
True if this segment is an arc, false for line.
Definition pads_parser.h:75
double y
Endpoint Y coordinate.
Definition pads_parser.h:74
double x
Endpoint X coordinate.
Definition pads_parser.h:73
double cx
Center X coordinate.
Definition pads_parser.h:58
double delta_angle
Arc sweep angle in degrees (positive = CCW)
Definition pads_parser.h:62
double cy
Center Y coordinate.
Definition pads_parser.h:59
A polyline that may contain arc segments.
Information about a single PADS layer.
std::string path
VECTOR2I center
VECTOR2I end
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:229
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
@ THERMAL
Use thermal relief for pads.
Definition zones.h:50