29#include <wx/filename.h>
67 if( aOutlines.empty() )
70 double minX = std::numeric_limits<double>::max();
71 double maxX = std::numeric_limits<double>::lowest();
72 double minY = std::numeric_limits<double>::max();
73 double maxY = std::numeric_limits<double>::lowest();
79 minX = std::min( minX, pt.
x );
80 maxX = std::max( maxX, pt.
x );
81 minY = std::min( minY, pt.
y );
82 maxY = std::max( maxY, pt.
y );
86 if( minX >= maxX || minY >= maxY )
100 return static_cast<int>( std::clamp<int64_t>( nm, INT_MIN, INT_MAX ) );
121 auto convertLayerType =
150 info.padsLayerNum = padsInfo.number;
151 info.name = padsInfo.name;
156 info.type = convertLayerType( padsInfo.layer_type );
158 std::string lowerName = padsInfo.name;
159 std::transform( lowerName.begin(), lowerName.end(), lowerName.begin(),
160 [](
unsigned char c )
162 return std::tolower( c );
165 bool isBottom = lowerName.find(
"bottom" ) != std::string::npos
166 || lowerName.find(
"bot" ) != std::string::npos;
178 if( padsInfo.number == 1 )
180 else if( padsInfo.number == aPadsLayerCount )
197 info.required = padsInfo.required;
203 if( aMappingHandler )
209 int requested = std::max( aPadsLayerCount, 2 );
220 m_reporter->Report( wxString::Format(
_(
"The PADS file declares %d copper layers; KiCad supports "
221 "%d, so the layers past that share the last inner layer." ),
234 if(
info.padsLayerNum == aPadsLayer )
251 std::vector<const PADS_IO::LAYER_INFO*> copperLayerInfos;
256 copperLayerInfos.push_back( &li );
259 bool hasStackupData =
false;
263 if( li->layer_thickness > 0.0 || li->dielectric_constant > 0.0 )
265 hasStackupData =
true;
270 if( !hasStackupData )
279 std::map<PCB_LAYER_ID, const PADS_IO::LAYER_INFO*> copperInfoMap;
286 copperInfoMap[kicadLayer] = li;
296 auto it = copperInfoMap.find( item->GetBrdLayerId() );
298 if( it != copperInfoMap.end() )
300 prevCopperInfo = it->second;
302 if( it->second->copper_thickness > 0.0 )
303 item->SetThickness(
ScaleSize( it->second->copper_thickness ) );
319 item->SetColor( wxT(
"White" ) );
323 item->SetColor( wxT(
"Green" ) );
334 if( aNetName.empty() )
339 if(
m_board->FindNet( wxName ) ==
nullptr )
353 if( aPts.size() == 1 && aPts[0].is_arc &&
std::abs( aPts[0].arc.delta_angle ) >= 359.0 )
358 constexpr int NUM_SEGS = 36;
360 for(
int i = 0; i < NUM_SEGS; i++ )
362 double angle = 2.0 *
M_PI * i / NUM_SEGS;
372 for(
size_t i = 1; i < aPts.size(); i++ )
381 for(
int j = 1; j < arcPoly.
PointCount(); j++ )
406 double dx = aCurr.
x - aPrev.
x;
407 double dy = aCurr.
y - aPrev.
y;
412 midX = ( aPrev.
x + aCurr.
x ) / 2.0 - dy / 2.0;
413 midY = ( aPrev.
y + aCurr.
y ) / 2.0 + dx / 2.0;
418 midX = ( aPrev.
x + aCurr.
x ) / 2.0 + dy / 2.0;
419 midY = ( aPrev.
y + aCurr.
y ) / 2.0 - dx / 2.0;
427 double startAngleRad = atan2( aPrev.
y - aCurr.
arc.
cy, aPrev.
x - aCurr.
arc.
cx );
448 m_reporter->Report( wxString::Format(
_(
"Text on unmapped layer %d assigned to Comments layer" ),
461 int scaledSize =
ScaleSize( padsText.height );
466 if( padsText.width > 0 )
470 text->SetTextAngle( textAngle );
477 text->SetPosition( pos + textShift );
479 if( padsText.hjust ==
"LEFT" )
481 else if( padsText.hjust ==
"RIGHT" )
486 if( padsText.vjust ==
"UP" )
488 else if( padsText.vjust ==
"DOWN" )
493 text->SetKeepUpright(
false );
494 text->SetLayer( textLayer );
497 text->SetMirrored( padsText.mirrored );
506 int keepoutIndex = 0;
510 if( ko.outline.size() < 3 )
516 if( ko.layers.empty() )
520 else if( ko.layers.size() == 1 )
528 m_reporter->Report( wxString::Format(
_(
"Skipping keepout on unmapped layer %d" ), ko.layers[0] ),
542 for(
int layer : ko.layers )
547 layerSet.
set( mappedLayer );
550 if( layerSet.none() )
579 zone->
SetZoneName( wxString::Format( wxT(
"%s_%d" ), typeName, ++keepoutIndex ) );
585 if( ko.outline.size() > 2 )
607 if( dim.points.size() < 2 )
619 if( dim.is_horizontal )
629 if( dim.is_horizontal )
643 if( dim.text_height > 0 )
645 int scaledSize =
ScaleSize( dim.text_height );
650 if( dim.text_width > 0 )
654 if( !dim.text.empty() )
664 if( dim.rotation != 0.0 )
684 aZone->
SetZoneName( wxString::Format( wxT(
"Cutout_%s" ),
709 const std::vector<PADS_IO::DIFF_PAIR_DEF>& aDiffPairs )
711 if( aDiffPairs.empty() )
716 auto isSerializable =
717 [](
const wxString& aName )
719 return !aName.EndsWith( wxS(
"\\" ) );
725 [](
const wxString& aName )
727 wxString out = aName;
729 out.Replace( wxS(
"'" ), wxS(
"\\'" ) );
730 out.Replace( wxS(
"\\" ), wxS(
"\\\\" ) );
731 out.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
732 out.Replace( wxS(
"\r" ), wxS(
"\\r" ) );
733 out.Replace( wxS(
"\n" ), wxS(
"\\n" ) );
739 [](
const wxString& aName )
741 wxString out = aName;
743 out.Replace( wxS(
"\\" ), wxS(
"\\\\" ) );
744 out.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
745 out.Replace( wxS(
"\r" ), wxS(
"\\r" ) );
746 out.Replace( wxS(
"\n" ), wxS(
"\\n" ) );
751 wxString customRules = wxT(
"(version 2)\n" );
752 bool hasAnyRule =
false;
756 if( dp.name.empty() || dp.gap <= 0 || dp.positive_net.empty() || dp.negative_net.empty() )
764 if( !isSerializable( posNet ) || !isSerializable( negNet ) )
768 m_reporter->Report( wxString::Format(
_(
"Skipped design rule for differential pair "
769 "'%s'; a net name ends with a backslash." ),
778 wxString gapStr = wxString::FromUTF8(
FormatDouble2Str( gapMm ) ) + wxT(
"mm" );
780 customRules += wxString::Format( wxT(
"\n(rule \"%s_gap\"\n" )
781 wxT(
" (condition \"A.NetName == '%s' && B.NetName == '%s'\")\n" )
782 wxT(
" (constraint clearance (min %s)))\n" ),
783 escapeSymbol( ruleName ), escapeOperand( posNet ),
784 escapeOperand( negNet ), gapStr );
792 wxFileName fn( aFileName );
793 fn.SetExt( wxT(
"kicad_dru" ) );
802 rulesFile.Open( fn.GetFullPath(), wxFile::write_excl );
805 if( !rulesFile.IsOpened() )
809 wxString msg = fn.FileExists() ?
_(
"Design rules for the imported differential pairs were not "
810 "written; '%s' already exists." )
811 :
_(
"Could not write design rules to '%s'." );
819 bool written = rulesFile.Write( customRules );
821 if( !rulesFile.Close() )
828 wxRemoveFile( fn.GetFullPath() );
832 m_reporter->Report( wxString::Format(
_(
"Could not write design rules to '%s'." ),
845 size_t trackCount = 0;
856 m_reporter->Report( wxString::Format(
_(
"Imported %zu footprints, %d nets, %zu tracks, %zu vias, %zu zones" ),
857 m_board->Footprints().size(),
m_board->GetNetCount(), trackCount, viaCount,
constexpr EDA_IU_SCALE pcbIUScale
@ BS_ITEM_TYPE_SILKSCREEN
@ BS_ITEM_TYPE_DIELECTRIC
@ BS_ITEM_TYPE_SOLDERMASK
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
BASE_SET & set(size_t pos)
Container for design settings for a BOARD object.
BOARD_STACKUP & GetStackupDescriptor()
void SetBoardThickness(int aThickness)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Manage one layer needed to make a physical board.
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
int BuildBoardThicknessFromStackup() const
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
Information pertinent to a Pcbnew printed circuit board.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Handle the data for a net.
PADS_LAYER_MAPPER m_layerMapper
void AppendArcPoints(SHAPE_LINE_CHAIN &aChain, const std::vector< PADS_IO::ARC_POINT > &aPts) const
Append PADS vertices to a chain, converting arc entries to polylines and expanding a lone full-circle...
VECTOR2I ScalePoint(double aX, double aY) const
PADS_UNIT_CONVERTER m_unitConverter
void WriteDiffPairRules(const wxString &aFileName, const std::vector< PADS_IO::DIFF_PAIR_DEF > &aDiffPairs)
Write a .kicad_dru beside aFileName carrying one clearance rule per differential pair with a gap.
bool SetOriginFromOutlines(const std::vector< PADS_IO::POLYLINE > &aOutlines)
Move the origin to the center of the board outline bounding box, which places the imported board near...
PCB_LAYER_ID GetMappedLayer(int aPadsLayer) const
std::map< wxString, PCB_LAYER_ID > m_layerMap
PADS_PCB_CONVERTER(BOARD *aBoard, REPORTER *aReporter)
void SetupLayers(const std::vector< PADS_IO::LAYER_INFO > &aPadsLayers, int aPadsLayerCount, const LAYER_MAPPING_HANDLER &aMappingHandler, bool aResolveUnknownTypeByName)
Resolve the PADS layer table to KiCad layers and apply the copper layer count to the board.
void EnsureNet(const std::string &aNetName)
SHAPE_ARC MakeMidpointArc(const PADS_IO::ARC_POINT &aPrev, const PADS_IO::ARC_POINT &aCurr, int aWidth) const
Build a SHAPE_ARC from two consecutive PADS points.
void LoadTexts(const std::vector< PADS_IO::TEXT > &aTexts)
void LoadDimensions(const std::vector< PADS_IO::DIMENSION > &aDimensions)
void ApplyPourSettings(ZONE *aZone, const PADS_IO::POUR &aPour, int aMaxPriority, const PADS_IO::PARAMETERS &aParams)
Apply the cutout or fill settings of aPour to a zone whose outline the caller has already built.
void LoadKeepouts(const std::vector< PADS_IO::KEEPOUT > &aKeepouts)
void SetOrigin(double aX, double aY)
std::vector< PADS_LAYER_INFO > m_layerInfos
int ScaleSize(double aVal) const
int ScaleCoord(double aVal, bool aIsX) const
void BuildStackup(const std::vector< PADS_IO::LAYER_INFO > &aPadsLayers)
Build the board stackup from the PADS physical layer data, if that data carries real thicknesses or d...
static constexpr double MM_TO_NM
void Update()
Update the dimension's cached text and geometry.
virtual void SetEnd(const VECTOR2I &aPoint)
virtual void SetStart(const VECTOR2I &aPoint)
void SetOverrideTextEnabled(bool aOverride)
void SetLineThickness(int aWidth)
void SetOverrideText(const wxString &aValue)
For better understanding of the points that make a dimension:
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
void SetTextAngle(const EDA_ANGLE &aAngle) override
A pure virtual class used to derive REPORTER objects from.
const SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError=DefaultAccuracyForPCB(), int *aActualError=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
Handle a list of polygons defining a copper zone.
void SetDoNotAllowPads(bool aEnable)
void SetMinThickness(int aMinThickness)
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuildBorderHatch)
Set all hatch parameters for the zone.
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
SHAPE_POLY_SET * Outline()
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetNet(NETINFO_ITEM *aNetInfo) override
Override that drops aNetInfo when this zone is in copper-thieving fill mode.
void SetThermalReliefGap(int aThermalReliefGap)
void SetDoNotAllowFootprints(bool aEnable)
void SetDoNotAllowZoneFills(bool aEnable)
void SetAssignedPriority(unsigned aPriority)
void SetPadConnection(ZONE_CONNECTION aPadConnection)
void SetZoneName(const wxString &aName)
static int GetDefaultHatchPitch()
double m_PadsPcbTextWidthScale
PADS text width scale factor for PCB imports.
double m_PadsPcbTextHeightScale
PADS text height scale factor for PCB imports.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
int PadsScaleCoord(double aVal, bool aIsX, double aOriginX, double aOriginY, double aScaleFactor)
Map a PADS board coordinate to a KiCad internal coordinate.
wxString ConvertText(const std::string &aText)
Decode text from a PADS file, which uses an 8-bit codepage rather than UTF-8.
wxString ConvertInvertedNetName(const std::string &aNetName)
Convert a PADS net name to KiCad notation.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
PADS_LAYER_TYPE
Functional categories of PADS layers, independent of specific layer numbers.
std::function< std::map< wxString, PCB_LAYER_ID >(const std::vector< INPUT_LAYER_DESC > &)> LAYER_MAPPING_HANDLER
Pointer to a function that takes a map of source and KiCad layers and returns a re-mapped version.
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
A polyline point that may instead be an arc segment.
ARC arc
Only valid when is_arc is true.
double layer_thickness
Dielectric, BASIC units.
double dielectric_constant
Er.
double thermal_line_width
THERLINEWID, THT.
double thermal_min_clearance
STMINCLEAR.
A polyline that may contain arc segments, used for board outlines and graphics.
bool is_cutout
POCUT piece.
std::string owner_pour
Parent pour, 7th header field.
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.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
VECTOR2< int32_t > VECTOR2I
@ FULL
pads are covered by copper